<script lang="ts">
export default async function ({
	PRIVATE_GLOBAL,
	TRIGGER_EVENT_NAME,
	onConnection,
	namespace = "/ws"
}) {
	if (!window.io) {
		(function (SocketIo) {
			window.io = SocketIo();
		})(function () {
			var define, module, exports;
			return (function e(t, n, r) {
				function s(o, u) {
					if (!n[o]) {
						if (!t[o]) {
							var a = typeof require == "function" && require;
							if (!u && a) return a(o, !0);
							if (i) return i(o, !0);
							var f = new Error("Cannot find module '" + o + "'");
							throw ((f.code = "MODULE_NOT_FOUND"), f);
						}
						var l = (n[o] = { exports: {} });
						t[o][0].call(
							l.exports,
							function (e) {
								var n = t[o][1][e];
								return s(n ? n : e);
							},
							l,
							l.exports,
							e,
							t,
							n,
							r
						);
					}
					return n[o].exports;
				}

				var i = typeof require == "function" && require;
				for (var o = 0; o < r.length; o++) s(r[o]);
				return s;
			})(
				{
					1: [
						function (_dereq_, module, exports) {
							module.exports = _dereq_("./lib/");
						},
						{ "./lib/": 2 }
					],

					2: [
						function (_dereq_, module, exports) {
							module.exports = _dereq_("./socket");

							/**
							 * Exports parser
							 *
							 * @api public
							 *
							 */
							module.exports.parser = _dereq_("engine.io-parser");
						},
						{ "./socket": 3, "engine.io-parser": 19 }
					],

					3: [
						function (_dereq_, module, exports) {
							(function (global) {
								/**
								 * Module dependencies.
								 */

								var transports = _dereq_("./transports");
								var Emitter = _dereq_("component-emitter");
								var debug = _dereq_("debug")("engine.io-client:socket");
								var index = _dereq_("indexof");
								var parser = _dereq_("engine.io-parser");
								var parseuri = _dereq_("parseuri");
								var parsejson = _dereq_("parsejson");
								var parseqs = _dereq_("parseqs");

								/**
								 * Module exports.
								 */

								module.exports = Socket;

								/**
								 * Noop function.
								 *
								 * @api private
								 */

								function noop() {}

								/**
								 * Socket constructor.
								 *
								 * @param {String|Object} uri or options
								 * @param {Object} options
								 * @api public
								 */

								function Socket(uri, opts) {
									if (!(this instanceof Socket)) return new Socket(uri, opts);

									opts = opts || {};

									if (uri && "object" == typeof uri) {
										opts = uri;
										uri = null;
									}

									if (uri) {
										uri = parseuri(uri);
										opts.hostname = uri.host;
										opts.secure =
											uri.protocol == "https" || uri.protocol == "wss";
										opts.port = uri.port;
										if (uri.query) opts.query = uri.query;
									} else if (opts.host) {
										opts.hostname = parseuri(opts.host).host;
									}

									this.secure =
										null != opts.secure
											? opts.secure
											: global.location && "https:" == location.protocol;

									if (opts.hostname && !opts.port) {
										// if no port is specified manually, use the protocol default
										opts.port = this.secure ? "443" : "80";
									}

									this.agent = opts.agent || false;
									this.hostname =
										opts.hostname ||
										(global.location ? location.hostname : "localhost");
									this.port =
										opts.port ||
										(global.location && location.port
											? location.port
											: this.secure
												? 443
												: 80);
									this.query = opts.query || {};
									if ("string" == typeof this.query)
										this.query = parseqs.decode(this.query);
									this.upgrade = false !== opts.upgrade;
									this.path =
										(opts.path || "/engine.io").replace(/\/$/, "") + "/";
									this.forceJSONP = !!opts.forceJSONP;
									this.jsonp = false !== opts.jsonp;
									this.forceBase64 = !!opts.forceBase64;
									this.enablesXDR = !!opts.enablesXDR;
									this.timestampParam = opts.timestampParam || "t";
									this.timestampRequests = opts.timestampRequests;
									this.transports = opts.transports || ["polling", "websocket"];
									this.readyState = "";
									this.writeBuffer = [];
									this.policyPort = opts.policyPort || 843;
									this.rememberUpgrade = opts.rememberUpgrade || false;
									this.binaryType = null;
									this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
									this.perMessageDeflate =
										false !== opts.perMessageDeflate
											? opts.perMessageDeflate || {}
											: false;

									if (true === this.perMessageDeflate)
										this.perMessageDeflate = {};
									if (
										this.perMessageDeflate &&
										null == this.perMessageDeflate.threshold
									) {
										this.perMessageDeflate.threshold = 1024;
									}

									// SSL options for Node.js client
									this.pfx = opts.pfx || null;
									this.key = opts.key || null;
									this.passphrase = opts.passphrase || null;
									this.cert = opts.cert || null;
									this.ca = opts.ca || null;
									this.ciphers = opts.ciphers || null;
									this.rejectUnauthorized =
										opts.rejectUnauthorized === undefined
											? null
											: opts.rejectUnauthorized;

									// other options for Node.js client
									var freeGlobal = typeof global == "object" && global;
									if (freeGlobal.global === freeGlobal) {
										if (
											opts.extraHeaders &&
											Object.keys(opts.extraHeaders).length > 0
										) {
											this.extraHeaders = opts.extraHeaders;
										}
									}

									this.open();
								}

								Socket.priorWebsocketSuccess = false;

								/**
								 * Mix in `Emitter`.
								 */

								Emitter(Socket.prototype);

								/**
								 * Protocol version.
								 *
								 * @api public
								 */

								Socket.protocol = parser.protocol; // this is an int

								/**
								 * Expose deps for legacy compatibility
								 * and standalone browser access.
								 */

								Socket.Socket = Socket;
								Socket.Transport = _dereq_("./transport");
								Socket.transports = _dereq_("./transports");
								Socket.parser = _dereq_("engine.io-parser");

								/**
								 * Creates transport of the given type.
								 *
								 * @param {String} transport name
								 * @return {Transport}
								 * @api private
								 */

								Socket.prototype.createTransport = function (name) {
									debug('creating transport "%s"', name);
									var query = clone(this.query);

									// append engine.io protocol identifier
									query.EIO = parser.protocol;

									// transport name
									query.transport = name;

									// session id if we already have one
									if (this.id) query.sid = this.id;

									var transport = new transports[name]({
										agent: this.agent,
										hostname: this.hostname,
										port: this.port,
										secure: this.secure,
										path: this.path,
										query: query,
										forceJSONP: this.forceJSONP,
										jsonp: this.jsonp,
										forceBase64: this.forceBase64,
										enablesXDR: this.enablesXDR,
										timestampRequests: this.timestampRequests,
										timestampParam: this.timestampParam,
										policyPort: this.policyPort,
										socket: this,
										pfx: this.pfx,
										key: this.key,
										passphrase: this.passphrase,
										cert: this.cert,
										ca: this.ca,
										ciphers: this.ciphers,
										rejectUnauthorized: this.rejectUnauthorized,
										perMessageDeflate: this.perMessageDeflate,
										extraHeaders: this.extraHeaders
									});

									return transport;
								};

								function clone(obj) {
									var o = {};
									for (var i in obj) {
										if (obj.hasOwnProperty(i)) {
											o[i] = obj[i];
										}
									}
									return o;
								}

								/**
								 * Initializes transport to use and starts probe.
								 *
								 * @api private
								 */
								Socket.prototype.open = function () {
									var transport;
									if (
										this.rememberUpgrade &&
										Socket.priorWebsocketSuccess &&
										this.transports.indexOf("websocket") != -1
									) {
										transport = "websocket";
									} else if (0 === this.transports.length) {
										// Emit error on next tick so it can be listened to
										var self = this;
										setTimeout(function () {
											self.emit("error", "No transports available");
										}, 0);
										return;
									} else {
										transport = this.transports[0];
									}
									this.readyState = "opening";

									// Retry with the next transport if the transport is disabled (jsonp: false)
									try {
										transport = this.createTransport(transport);
									} catch (e) {
										this.transports.shift();
										this.open();
										return;
									}

									transport.open();
									this.setTransport(transport);
								};

								/**
								 * Sets the current transport. Disables the existing one (if any).
								 *
								 * @api private
								 */

								Socket.prototype.setTransport = function (transport) {
									debug("setting transport %s", transport.name);
									var self = this;

									if (this.transport) {
										debug(
											"clearing existing transport %s",
											this.transport.name
										);
										this.transport.removeAllListeners();
									}

									// set up transport
									this.transport = transport;

									// set up transport listeners
									transport
										.on("drain", function () {
											self.onDrain();
										})
										.on("packet", function (packet) {
											self.onPacket(packet);
										})
										.on("error", function (e) {
											self.onError(e);
										})
										.on("close", function () {
											self.onClose("transport close");
										});
								};

								/**
								 * Probes a transport.
								 *
								 * @param {String} transport name
								 * @api private
								 */

								Socket.prototype.probe = function (name) {
									debug('probing transport "%s"', name);
									var transport = this.createTransport(name, { probe: 1 }),
										failed = false,
										self = this;

									Socket.priorWebsocketSuccess = false;

									function onTransportOpen() {
										if (self.onlyBinaryUpgrades) {
											var upgradeLosesBinary =
												!this.supportsBinary &&
												self.transport.supportsBinary;
											failed = failed || upgradeLosesBinary;
										}
										if (failed) return;

										debug('probe transport "%s" opened', name);
										transport.send([{ type: "ping", data: "probe" }]);
										transport.once("packet", function (msg) {
											if (failed) return;
											if ("pong" == msg.type && "probe" == msg.data) {
												debug('probe transport "%s" pong', name);
												self.upgrading = true;
												self.emit("upgrading", transport);
												if (!transport) return;
												Socket.priorWebsocketSuccess =
													"websocket" == transport.name;

												debug(
													'pausing current transport "%s"',
													self.transport.name
												);
												self.transport.pause(function () {
													if (failed) return;
													if ("closed" == self.readyState) return;
													debug(
														"changing transport and sending upgrade packet"
													);

													cleanup();

													self.setTransport(transport);
													transport.send([{ type: "upgrade" }]);
													self.emit("upgrade", transport);
													transport = null;
													self.upgrading = false;
													self.flush();
												});
											} else {
												debug('probe transport "%s" failed', name);
												var err = new Error("probe error");
												err.transport = transport.name;
												self.emit("upgradeError", err);
											}
										});
									}

									function freezeTransport() {
										if (failed) return;

										// Any callback called by transport should be ignored since now
										failed = true;

										cleanup();

										transport.close();
										transport = null;
									}

									//Handle any error that happens while probing
									function onerror(err) {
										var error = new Error("probe error: " + err);
										error.transport = transport.name;

										freezeTransport();

										debug(
											'probe transport "%s" failed because of error: %s',
											name,
											err
										);

										self.emit("upgradeError", error);
									}

									function onTransportClose() {
										onerror("transport closed");
									}

									//When the socket is closed while we're probing
									function onclose() {
										onerror("socket closed");
									}

									//When the socket is upgraded while we're probing
									function onupgrade(to) {
										if (transport && to.name != transport.name) {
											debug(
												'"%s" works - aborting "%s"',
												to.name,
												transport.name
											);
											freezeTransport();
										}
									}

									//Remove all listeners on the transport and on self
									function cleanup() {
										transport.removeListener("open", onTransportOpen);
										transport.removeListener("error", onerror);
										transport.removeListener("close", onTransportClose);
										self.removeListener("close", onclose);
										self.removeListener("upgrading", onupgrade);
									}

									transport.once("open", onTransportOpen);
									transport.once("error", onerror);
									transport.once("close", onTransportClose);

									this.once("close", onclose);
									this.once("upgrading", onupgrade);

									transport.open();
								};

								/**
								 * Called when connection is deemed open.
								 *
								 * @api public
								 */

								Socket.prototype.onOpen = function () {
									debug("socket open");
									this.readyState = "open";
									Socket.priorWebsocketSuccess =
										"websocket" == this.transport.name;
									this.emit("open");
									this.flush();

									// we check for `readyState` in case an `open`
									// listener already closed the socket
									if (
										"open" == this.readyState &&
										this.upgrade &&
										this.transport.pause
									) {
										debug("starting upgrade probes");
										for (var i = 0, l = this.upgrades.length; i < l; i++) {
											this.probe(this.upgrades[i]);
										}
									}
								};

								/**
								 * Handles a packet.
								 *
								 * @api private
								 */

								Socket.prototype.onPacket = function (packet) {
									if ("opening" == this.readyState || "open" == this.readyState) {
										debug(
											'socket receive: type "%s", data "%s"',
											packet.type,
											packet.data
										);

										this.emit("packet", packet);

										// Socket is live - any packet counts
										this.emit("heartbeat");

										switch (packet.type) {
											case "open":
												this.onHandshake(parsejson(packet.data));
												break;

											case "pong":
												this.setPing();
												this.emit("pong");
												break;

											case "error":
												var err = new Error("server error");
												err.code = packet.data;
												this.onError(err);
												break;

											case "message":
												this.emit("data", packet.data);
												this.emit("message", packet.data);
												break;
										}
									} else {
										debug(
											'packet received with socket readyState "%s"',
											this.readyState
										);
									}
								};

								/**
								 * Called upon handshake completion.
								 *
								 * @param {Object} handshake obj
								 * @api private
								 */

								Socket.prototype.onHandshake = function (data) {
									this.emit("handshake", data);
									this.id = data.sid;
									this.transport.query.sid = data.sid;
									this.upgrades = this.filterUpgrades(data.upgrades);
									this.pingInterval = data.pingInterval;
									this.pingTimeout = data.pingTimeout;
									this.onOpen();
									// In case open handler closes socket
									if ("closed" == this.readyState) return;
									this.setPing();

									// Prolong liveness of socket on heartbeat
									this.removeListener("heartbeat", this.onHeartbeat);
									this.on("heartbeat", this.onHeartbeat);
								};

								/**
								 * Resets ping timeout.
								 *
								 * @api private
								 */

								Socket.prototype.onHeartbeat = function (timeout) {
									clearTimeout(this.pingTimeoutTimer);
									var self = this;
									self.pingTimeoutTimer = setTimeout(
										function () {
											if ("closed" == self.readyState) return;
											self.onClose("ping timeout");
										},
										timeout || self.pingInterval + self.pingTimeout
									);
								};

								/**
								 * Pings server every `this.pingInterval` and expects response
								 * within `this.pingTimeout` or closes connection.
								 *
								 * @api private
								 */

								Socket.prototype.setPing = function () {
									var self = this;
									clearTimeout(self.pingIntervalTimer);
									self.pingIntervalTimer = setTimeout(function () {
										debug(
											"writing ping packet - expecting pong within %sms",
											self.pingTimeout
										);
										self.ping();
										self.onHeartbeat(self.pingTimeout);
									}, self.pingInterval);
								};

								/**
								 * Sends a ping packet.
								 *
								 * @api private
								 */

								Socket.prototype.ping = function () {
									var self = this;
									this.sendPacket("ping", function () {
										self.emit("ping");
									});
								};

								/**
								 * Called on `drain` event
								 *
								 * @api private
								 */

								Socket.prototype.onDrain = function () {
									this.writeBuffer.splice(0, this.prevBufferLen);

									// setting prevBufferLen = 0 is very important
									// for example, when upgrading, upgrade packet is sent over,
									// and a nonzero prevBufferLen could cause problems on `drain`
									this.prevBufferLen = 0;

									if (0 === this.writeBuffer.length) {
										this.emit("drain");
									} else {
										this.flush();
									}
								};

								/**
								 * Flush write buffers.
								 *
								 * @api private
								 */

								Socket.prototype.flush = function () {
									if (
										"closed" != this.readyState &&
										this.transport.writable &&
										!this.upgrading &&
										this.writeBuffer.length
									) {
										debug(
											"flushing %d packets in socket",
											this.writeBuffer.length
										);
										this.transport.send(this.writeBuffer);
										// keep track of current length of writeBuffer
										// splice writeBuffer and callbackBuffer on `drain`
										this.prevBufferLen = this.writeBuffer.length;
										this.emit("flush");
									}
								};

								/**
								 * Sends a message.
								 *
								 * @param {String} message.
								 * @param {Function} callback function.
								 * @param {Object} options.
								 * @return {Socket} for chaining.
								 * @api public
								 */

								Socket.prototype.write = Socket.prototype.send = function (
									msg,
									options,
									fn
								) {
									this.sendPacket("message", msg, options, fn);
									return this;
								};

								/**
								 * Sends a packet.
								 *
								 * @param {String} packet type.
								 * @param {String} data.
								 * @param {Object} options.
								 * @param {Function} callback function.
								 * @api private
								 */

								Socket.prototype.sendPacket = function (type, data, options, fn) {
									if ("function" == typeof data) {
										fn = data;
										data = undefined;
									}

									if ("function" == typeof options) {
										fn = options;
										options = null;
									}

									if (
										"closing" == this.readyState ||
										"closed" == this.readyState
									) {
										return;
									}

									options = options || {};
									options.compress = false !== options.compress;

									var packet = {
										type: type,
										data: data,
										options: options
									};
									this.emit("packetCreate", packet);
									this.writeBuffer.push(packet);
									if (fn) this.once("flush", fn);
									this.flush();
								};

								/**
								 * Closes the connection.
								 *
								 * @api private
								 */

								Socket.prototype.close = function () {
									if ("opening" == this.readyState || "open" == this.readyState) {
										this.readyState = "closing";

										var self = this;

										if (this.writeBuffer.length) {
											this.once("drain", function () {
												if (this.upgrading) {
													waitForUpgrade();
												} else {
													close();
												}
											});
										} else if (this.upgrading) {
											waitForUpgrade();
										} else {
											close();
										}
									}

									function close() {
										self.onClose("forced close");
										debug("socket closing - telling transport to close");
										self.transport.close();
									}

									function cleanupAndClose() {
										self.removeListener("upgrade", cleanupAndClose);
										self.removeListener("upgradeError", cleanupAndClose);
										close();
									}

									function waitForUpgrade() {
										// wait for upgrade to finish since we can't send packets while pausing a transport
										self.once("upgrade", cleanupAndClose);
										self.once("upgradeError", cleanupAndClose);
									}

									return this;
								};

								/**
								 * Called upon transport error
								 *
								 * @api private
								 */

								Socket.prototype.onError = function (err) {
									debug("socket error %j", err);
									Socket.priorWebsocketSuccess = false;
									this.emit("error", err);
									this.onClose("transport error", err);
								};

								/**
								 * Called upon transport close.
								 *
								 * @api private
								 */

								Socket.prototype.onClose = function (reason, desc) {
									if (
										"opening" == this.readyState ||
										"open" == this.readyState ||
										"closing" == this.readyState
									) {
										debug('socket close with reason: "%s"', reason);
										var self = this;

										// clear timers
										clearTimeout(this.pingIntervalTimer);
										clearTimeout(this.pingTimeoutTimer);

										// stop event from firing again for transport
										this.transport.removeAllListeners("close");

										// ensure transport won't stay open
										this.transport.close();

										// ignore further transport communication
										this.transport.removeAllListeners();

										// set ready state
										this.readyState = "closed";

										// clear session id
										this.id = null;

										// emit close event
										this.emit("close", reason, desc);

										// clean buffers after, so users can still
										// grab the buffers on `close` event
										self.writeBuffer = [];
										self.prevBufferLen = 0;
									}
								};

								/**
								 * Filters upgrades, returning only those matching client transports.
								 *
								 * @param {Array} server upgrades
								 * @api private
								 *
								 */

								Socket.prototype.filterUpgrades = function (upgrades) {
									var filteredUpgrades = [];
									for (var i = 0, j = upgrades.length; i < j; i++) {
										if (~index(this.transports, upgrades[i]))
											filteredUpgrades.push(upgrades[i]);
									}
									return filteredUpgrades;
								};
							}).call(
								window,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{
							"./transport": 4,
							"./transports": 5,
							"component-emitter": 15,
							debug: 17,
							"engine.io-parser": 19,
							indexof: 23,
							parsejson: 26,
							parseqs: 27,
							parseuri: 28
						}
					],

					4: [
						function (_dereq_, module, exports) {
							/**
							 * Module dependencies.
							 */

							var parser = _dereq_("engine.io-parser");
							var Emitter = _dereq_("component-emitter");

							/**
							 * Module exports.
							 */

							module.exports = Transport;

							/**
							 * Transport abstract constructor.
							 *
							 * @param {Object} options.
							 * @api private
							 */

							function Transport(opts) {
								this.path = opts.path;
								this.hostname = opts.hostname;
								this.port = opts.port;
								this.secure = opts.secure;
								this.query = opts.query;
								this.timestampParam = opts.timestampParam;
								this.timestampRequests = opts.timestampRequests;
								this.readyState = "";
								this.agent = opts.agent || false;
								this.socket = opts.socket;
								this.enablesXDR = opts.enablesXDR;

								// SSL options for Node.js client
								this.pfx = opts.pfx;
								this.key = opts.key;
								this.passphrase = opts.passphrase;
								this.cert = opts.cert;
								this.ca = opts.ca;
								this.ciphers = opts.ciphers;
								this.rejectUnauthorized = opts.rejectUnauthorized;

								// other options for Node.js client
								this.extraHeaders = opts.extraHeaders;
							}

							/**
							 * Mix in `Emitter`.
							 */

							Emitter(Transport.prototype);

							/**
							 * Emits an error.
							 *
							 * @param {String} str
							 * @return {Transport} for chaining
							 * @api public
							 */

							Transport.prototype.onError = function (msg, desc) {
								var err = new Error(msg);
								err.type = "TransportError";
								err.description = desc;
								this.emit("error", err);
								return this;
							};

							/**
							 * Opens the transport.
							 *
							 * @api public
							 */

							Transport.prototype.open = function () {
								if ("closed" == this.readyState || "" == this.readyState) {
									this.readyState = "opening";
									this.doOpen();
								}

								return this;
							};

							/**
							 * Closes the transport.
							 *
							 * @api private
							 */

							Transport.prototype.close = function () {
								if ("opening" == this.readyState || "open" == this.readyState) {
									this.doClose();
									this.onClose();
								}

								return this;
							};

							/**
							 * Sends multiple packets.
							 *
							 * @param {Array} packets
							 * @api private
							 */

							Transport.prototype.send = function (packets) {
								if ("open" == this.readyState) {
									this.write(packets);
								} else {
									throw new Error("Transport not open");
								}
							};

							/**
							 * Called upon open
							 *
							 * @api private
							 */

							Transport.prototype.onOpen = function () {
								this.readyState = "open";
								this.writable = true;
								this.emit("open");
							};

							/**
							 * Called with data.
							 *
							 * @param {String} data
							 * @api private
							 */

							Transport.prototype.onData = function (data) {
								var packet = parser.decodePacket(data, this.socket.binaryType);
								this.onPacket(packet);
							};

							/**
							 * Called with a decoded packet.
							 */

							Transport.prototype.onPacket = function (packet) {
								this.emit("packet", packet);
							};

							/**
							 * Called upon close.
							 *
							 * @api private
							 */

							Transport.prototype.onClose = function () {
								this.readyState = "closed";
								this.emit("close");
							};
						},
						{ "component-emitter": 15, "engine.io-parser": 19 }
					],

					5: [
						function (_dereq_, module, exports) {
							(function (global) {
								/**
								 * Module dependencies
								 */

								var XMLHttpRequest = _dereq_("xmlhttprequest-ssl");
								var XHR = _dereq_("./polling-xhr");
								var JSONP = _dereq_("./polling-jsonp");
								var websocket = _dereq_("./websocket");

								/**
								 * Export transports.
								 */

								exports.polling = polling;
								exports.websocket = websocket;

								/**
								 * Polling transport polymorphic constructor.
								 * Decides on xhr vs jsonp based on feature detection.
								 *
								 * @api private
								 */

								function polling(opts) {
									var xhr;
									var xd = false;
									var xs = false;
									var jsonp = false !== opts.jsonp;

									if (global.location) {
										var isSSL = "https:" == location.protocol;
										var port = location.port;

										// some user agents have empty `location.port`
										if (!port) {
											port = isSSL ? 443 : 80;
										}

										xd =
											opts.hostname != location.hostname || port != opts.port;
										xs = opts.secure != isSSL;
									}

									opts.xdomain = xd;
									opts.xscheme = xs;
									xhr = new XMLHttpRequest(opts);

									if ("open" in xhr && !opts.forceJSONP) {
										return new XHR(opts);
									} else {
										if (!jsonp) throw new Error("JSONP disabled");
										return new JSONP(opts);
									}
								}
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{
							"./polling-jsonp": 6,
							"./polling-xhr": 7,
							"./websocket": 9,
							"xmlhttprequest-ssl": 10
						}
					],

					6: [
						function (_dereq_, module, exports) {
							(function (global) {
								/**
								 * Module requirements.
								 */

								var Polling = _dereq_("./polling");
								var inherit = _dereq_("component-inherit");

								/**
								 * Module exports.
								 */

								module.exports = JSONPPolling;

								/**
								 * Cached regular expressions.
								 */

								var rNewline = /\n/g;
								var rEscapedNewline = /\\n/g;

								/**
								 * Global JSONP callbacks.
								 */

								var callbacks;

								/**
								 * Callbacks count.
								 */

								var index = 0;

								/**
								 * Noop.
								 */

								function empty() {}

								/**
								 * JSONP Polling constructor.
								 *
								 * @param {Object} opts.
								 * @api public
								 */

								function JSONPPolling(opts) {
									Polling.call(this, opts);

									this.query = this.query || {};

									// define global callbacks array if not present
									// we do this here (lazily) to avoid unneeded global pollution
									if (!callbacks) {
										// we need to consider multiple engines in the same page
										if (!global.___eio) global.___eio = [];
										callbacks = global.___eio;
									}

									// callback identifier
									this.index = callbacks.length;

									// add callback to jsonp global
									var self = this;
									callbacks.push(function (msg) {
										self.onData(msg);
									});

									// append to query string
									this.query.j = this.index;

									// prevent spurious errors from being emitted when the window is unloaded
									if (global.document && global.addEventListener) {
										global.addEventListener(
											"beforeunload",
											function () {
												if (self.script) self.script.onerror = empty;
											},
											false
										);
									}
								}

								/**
								 * Inherits from Polling.
								 */

								inherit(JSONPPolling, Polling);

								/*
								 * JSONP only supports binary as base64 encoded strings
								 */

								JSONPPolling.prototype.supportsBinary = false;

								/**
								 * Closes the socket.
								 *
								 * @api private
								 */

								JSONPPolling.prototype.doClose = function () {
									if (this.script) {
										this.script.parentNode.removeChild(this.script);
										this.script = null;
									}

									if (this.form) {
										this.form.parentNode.removeChild(this.form);
										this.form = null;
										this.iframe = null;
									}

									Polling.prototype.doClose.call(this);
								};

								/**
								 * Starts a poll cycle.
								 *
								 * @api private
								 */

								JSONPPolling.prototype.doPoll = function () {
									var self = this;
									var script = document.createElement("script");

									if (this.script) {
										this.script.parentNode.removeChild(this.script);
										this.script = null;
									}

									script.async = true;
									script.src = this.uri();
									script.onerror = function (e) {
										self.onError("jsonp poll error", e);
									};

									var insertAt = document.getElementsByTagName("script")[0];
									if (insertAt) {
										insertAt.parentNode.insertBefore(script, insertAt);
									} else {
										(document.head || document.body).appendChild(script);
									}
									this.script = script;

									var isUAgecko =
										"undefined" != typeof navigator &&
										/gecko/i.test(navigator.userAgent);

									if (isUAgecko) {
										setTimeout(function () {
											var iframe = document.createElement("iframe");
											document.body.appendChild(iframe);
											document.body.removeChild(iframe);
										}, 100);
									}
								};

								/**
								 * Writes with a hidden iframe.
								 *
								 * @param {String} data to send
								 * @param {Function} called upon flush.
								 * @api private
								 */

								JSONPPolling.prototype.doWrite = function (data, fn) {
									var self = this;

									if (!this.form) {
										var form = document.createElement("form");
										var area = document.createElement("textarea");
										var id = (this.iframeId = "eio_iframe_" + this.index);
										var iframe;

										form.className = "socketio";
										form.style.position = "absolute";
										form.style.top = "-1000px";
										form.style.left = "-1000px";
										form.target = id;
										form.method = "POST";
										form.setAttribute("accept-charset", "utf-8");
										area.name = "d";
										form.appendChild(area);
										document.body.appendChild(form);

										this.form = form;
										this.area = area;
									}

									this.form.action = this.uri();

									function complete() {
										initIframe();
										fn();
									}

									function initIframe() {
										if (self.iframe) {
											try {
												self.form.removeChild(self.iframe);
											} catch (e) {
												self.onError(
													"jsonp polling iframe removal error",
													e
												);
											}
										}

										try {
											// ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
											var html =
												'<iframe src="javascript:0" name="' +
												self.iframeId +
												'">';
											iframe = document.createElement(html);
										} catch (e) {
											iframe = document.createElement("iframe");
											iframe.name = self.iframeId;
											iframe.src = "javascript:0";
										}

										iframe.id = self.iframeId;

										self.form.appendChild(iframe);
										self.iframe = iframe;
									}

									initIframe();

									// escape \n to prevent it from being converted into \r\n by some UAs
									// double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side
									data = data.replace(rEscapedNewline, "\\\n");
									this.area.value = data.replace(rNewline, "\\n");

									try {
										this.form.submit();
									} catch (e) {}

									if (this.iframe.attachEvent) {
										this.iframe.onreadystatechange = function () {
											if (self.iframe.readyState == "complete") {
												complete();
											}
										};
									} else {
										this.iframe.onload = complete;
									}
								};
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{ "./polling": 8, "component-inherit": 16 }
					],

					7: [
						function (_dereq_, module, exports) {
							(function (global) {
								/**
								 * Module requirements.
								 */

								var XMLHttpRequest = _dereq_("xmlhttprequest-ssl");
								var Polling = _dereq_("./polling");
								var Emitter = _dereq_("component-emitter");
								var inherit = _dereq_("component-inherit");
								var debug = _dereq_("debug")("engine.io-client:polling-xhr");

								/**
								 * Module exports.
								 */

								module.exports = XHR;
								module.exports.Request = Request;

								/**
								 * Empty function
								 */

								function empty() {}

								/**
								 * XHR Polling constructor.
								 *
								 * @param {Object} opts
								 * @api public
								 */

								function XHR(opts) {
									Polling.call(this, opts);

									if (global.location) {
										var isSSL = "https:" == location.protocol;
										var port = location.port;

										// some user agents have empty `location.port`
										if (!port) {
											port = isSSL ? 443 : 80;
										}

										this.xd =
											opts.hostname != global.location.hostname ||
											port != opts.port;
										this.xs = opts.secure != isSSL;
									} else {
										this.extraHeaders = opts.extraHeaders;
									}
								}

								/**
								 * Inherits from Polling.
								 */

								inherit(XHR, Polling);

								/**
								 * XHR supports binary
								 */

								XHR.prototype.supportsBinary = true;

								/**
								 * Creates a request.
								 *
								 * @param {String} method
								 * @api private
								 */

								XHR.prototype.request = function (opts) {
									opts = opts || {};
									opts.uri = this.uri();
									opts.xd = this.xd;
									opts.xs = this.xs;
									opts.agent = this.agent || false;
									opts.supportsBinary = this.supportsBinary;
									opts.enablesXDR = this.enablesXDR;

									// SSL options for Node.js client
									opts.pfx = this.pfx;
									opts.key = this.key;
									opts.passphrase = this.passphrase;
									opts.cert = this.cert;
									opts.ca = this.ca;
									opts.ciphers = this.ciphers;
									opts.rejectUnauthorized = this.rejectUnauthorized;

									// other options for Node.js client
									opts.extraHeaders = this.extraHeaders;

									return new Request(opts);
								};

								/**
								 * Sends data.
								 *
								 * @param {String} data to send.
								 * @param {Function} called upon flush.
								 * @api private
								 */

								XHR.prototype.doWrite = function (data, fn) {
									var isBinary = typeof data !== "string" && data !== undefined;
									var req = this.request({
										method: "POST",
										data: data,
										isBinary: isBinary
									});
									var self = this;
									req.on("success", fn);
									req.on("error", function (err) {
										self.onError("xhr post error", err);
									});
									this.sendXhr = req;
								};

								/**
								 * Starts a poll cycle.
								 *
								 * @api private
								 */

								XHR.prototype.doPoll = function () {
									debug("xhr poll");
									var req = this.request();
									var self = this;
									req.on("data", function (data) {
										self.onData(data);
									});
									req.on("error", function (err) {
										self.onError("xhr poll error", err);
									});
									this.pollXhr = req;
								};

								/**
								 * Request constructor
								 *
								 * @param {Object} options
								 * @api public
								 */

								function Request(opts) {
									this.method = opts.method || "GET";
									this.uri = opts.uri;
									this.xd = !!opts.xd;
									this.xs = !!opts.xs;
									this.async = false !== opts.async;
									this.data = undefined != opts.data ? opts.data : null;
									this.agent = opts.agent;
									this.isBinary = opts.isBinary;
									this.supportsBinary = opts.supportsBinary;
									this.enablesXDR = opts.enablesXDR;

									// SSL options for Node.js client
									this.pfx = opts.pfx;
									this.key = opts.key;
									this.passphrase = opts.passphrase;
									this.cert = opts.cert;
									this.ca = opts.ca;
									this.ciphers = opts.ciphers;
									this.rejectUnauthorized = opts.rejectUnauthorized;

									// other options for Node.js client
									this.extraHeaders = opts.extraHeaders;

									this.create();
								}

								/**
								 * Mix in `Emitter`.
								 */

								Emitter(Request.prototype);

								/**
								 * Creates the XHR object and sends the request.
								 *
								 * @api private
								 */

								Request.prototype.create = function () {
									var opts = {
										agent: this.agent,
										xdomain: this.xd,
										xscheme: this.xs,
										enablesXDR: this.enablesXDR
									};

									// SSL options for Node.js client
									opts.pfx = this.pfx;
									opts.key = this.key;
									opts.passphrase = this.passphrase;
									opts.cert = this.cert;
									opts.ca = this.ca;
									opts.ciphers = this.ciphers;
									opts.rejectUnauthorized = this.rejectUnauthorized;

									var xhr = (this.xhr = new XMLHttpRequest(opts));
									var self = this;

									try {
										debug("xhr open %s: %s", this.method, this.uri);
										xhr.open(this.method, this.uri, this.async);
										try {
											if (this.extraHeaders) {
												xhr.setDisableHeaderCheck(true);
												for (var i in this.extraHeaders) {
													if (this.extraHeaders.hasOwnProperty(i)) {
														xhr.setRequestHeader(
															i,
															this.extraHeaders[i]
														);
													}
												}
											}
										} catch (e) {}
										if (this.supportsBinary) {
											// This has to be done after open because Firefox is stupid
											// http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension
											xhr.responseType = "arraybuffer";
										}

										if ("POST" == this.method) {
											try {
												if (this.isBinary) {
													xhr.setRequestHeader(
														"Content-type",
														"application/octet-stream"
													);
												} else {
													xhr.setRequestHeader(
														"Content-type",
														"text/plain;charset=UTF-8"
													);
												}
											} catch (e) {}
										}

										// ie6 check
										if ("withCredentials" in xhr) {
											xhr.withCredentials = true;
										}

										if (this.hasXDR()) {
											xhr.onload = function () {
												self.onLoad();
											};
											xhr.onerror = function () {
												self.onError(xhr.responseText);
											};
										} else {
											xhr.onreadystatechange = function () {
												if (4 != xhr.readyState) return;
												if (200 == xhr.status || 1223 == xhr.status) {
													self.onLoad();
												} else {
													// make sure the `error` event handler that's user-set
													// does not throw in the same tick and gets caught here
													setTimeout(function () {
														self.onError(xhr.status);
													}, 0);
												}
											};
										}

										debug("xhr data %s", this.data);
										xhr.send(this.data);
									} catch (e) {
										// Need to defer since .create() is called directly fhrom the constructor
										// and thus the 'error' event can only be only bound *after* this exception
										// occurs.  Therefore, also, we cannot throw here at all.
										setTimeout(function () {
											self.onError(e);
										}, 0);
										return;
									}

									if (global.document) {
										this.index = Request.requestsCount++;
										Request.requests[this.index] = this;
									}
								};

								/**
								 * Called upon successful response.
								 *
								 * @api private
								 */

								Request.prototype.onSuccess = function () {
									this.emit("success");
									this.cleanup();
								};

								/**
								 * Called if we have data.
								 *
								 * @api private
								 */

								Request.prototype.onData = function (data) {
									this.emit("data", data);
									this.onSuccess();
								};

								/**
								 * Called upon error.
								 *
								 * @api private
								 */

								Request.prototype.onError = function (err) {
									this.emit("error", err);
									this.cleanup(true);
								};

								/**
								 * Cleans up house.
								 *
								 * @api private
								 */

								Request.prototype.cleanup = function (fromError) {
									if ("undefined" == typeof this.xhr || null === this.xhr) {
										return;
									}
									// xmlhttprequest
									if (this.hasXDR()) {
										this.xhr.onload = this.xhr.onerror = empty;
									} else {
										this.xhr.onreadystatechange = empty;
									}

									if (fromError) {
										try {
											this.xhr.abort();
										} catch (e) {}
									}

									if (global.document) {
										delete Request.requests[this.index];
									}

									this.xhr = null;
								};

								/**
								 * Called upon load.
								 *
								 * @api private
								 */

								Request.prototype.onLoad = function () {
									var data;
									try {
										var contentType;
										try {
											contentType = this.xhr
												.getResponseHeader("Content-Type")
												.split(";")[0];
										} catch (e) {}
										if (contentType === "application/octet-stream") {
											data = this.xhr.response;
										} else {
											if (!this.supportsBinary) {
												data = this.xhr.responseText;
											} else {
												try {
													data = String.fromCharCode.apply(
														null,
														new Uint8Array(this.xhr.response)
													);
												} catch (e) {
													var ui8Arr = new Uint8Array(this.xhr.response);
													var dataArray = [];
													for (
														var idx = 0, length = ui8Arr.length;
														idx < length;
														idx++
													) {
														dataArray.push(ui8Arr[idx]);
													}

													data = String.fromCharCode.apply(
														null,
														dataArray
													);
												}
											}
										}
									} catch (e) {
										this.onError(e);
									}
									if (null != data) {
										this.onData(data);
									}
								};

								/**
								 * Check if it has XDomainRequest.
								 *
								 * @api private
								 */

								Request.prototype.hasXDR = function () {
									return (
										"undefined" !== typeof global.XDomainRequest &&
										!this.xs &&
										this.enablesXDR
									);
								};

								/**
								 * Aborts the request.
								 *
								 * @api public
								 */

								Request.prototype.abort = function () {
									this.cleanup();
								};

								/**
								 * Aborts pending requests when unloading the window. This is needed to prevent
								 * memory leaks (e.g. when using IE) and to ensure that no spurious error is
								 * emitted.
								 */

								if (global.document) {
									Request.requestsCount = 0;
									Request.requests = {};
									if (global.attachEvent) {
										global.attachEvent("onunload", unloadHandler);
									} else if (global.addEventListener) {
										global.addEventListener(
											"beforeunload",
											unloadHandler,
											false
										);
									}
								}

								function unloadHandler() {
									for (var i in Request.requests) {
										if (Request.requests.hasOwnProperty(i)) {
											Request.requests[i].abort();
										}
									}
								}
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{
							"./polling": 8,
							"component-emitter": 15,
							"component-inherit": 16,
							debug: 17,
							"xmlhttprequest-ssl": 10
						}
					],

					8: [
						function (_dereq_, module, exports) {
							/**
							 * Module dependencies.
							 */

							var Transport = _dereq_("../transport");
							var parseqs = _dereq_("parseqs");
							var parser = _dereq_("engine.io-parser");
							var inherit = _dereq_("component-inherit");
							var yeast = _dereq_("yeast");
							var debug = _dereq_("debug")("engine.io-client:polling");

							/**
							 * Module exports.
							 */

							module.exports = Polling;

							/**
							 * Is XHR2 supported?
							 */

							var hasXHR2 = (function () {
								var XMLHttpRequest = _dereq_("xmlhttprequest-ssl");
								var xhr = new XMLHttpRequest({ xdomain: false });
								return null != xhr.responseType;
							})();

							/**
							 * Polling interface.
							 *
							 * @param {Object} opts
							 * @api private
							 */

							function Polling(opts) {
								var forceBase64 = opts && opts.forceBase64;
								if (!hasXHR2 || forceBase64) {
									this.supportsBinary = false;
								}
								Transport.call(this, opts);
							}

							/**
							 * Inherits from Transport.
							 */

							inherit(Polling, Transport);

							/**
							 * Transport name.
							 */

							Polling.prototype.name = "polling";

							/**
							 * Opens the socket (triggers polling). We write a PING message to determine
							 * when the transport is open.
							 *
							 * @api private
							 */

							Polling.prototype.doOpen = function () {
								this.poll();
							};

							/**
							 * Pauses polling.
							 *
							 * @param {Function} callback upon buffers are flushed and transport is paused
							 * @api private
							 */

							Polling.prototype.pause = function (onPause) {
								var pending = 0;
								var self = this;

								this.readyState = "pausing";

								function pause() {
									debug("paused");
									self.readyState = "paused";
									onPause();
								}

								if (this.polling || !this.writable) {
									var total = 0;

									if (this.polling) {
										debug("we are currently polling - waiting to pause");
										total++;
										this.once("pollComplete", function () {
											debug("pre-pause polling complete");
											--total || pause();
										});
									}

									if (!this.writable) {
										debug("we are currently writing - waiting to pause");
										total++;
										this.once("drain", function () {
											debug("pre-pause writing complete");
											--total || pause();
										});
									}
								} else {
									pause();
								}
							};

							/**
							 * Starts polling cycle.
							 *
							 * @api public
							 */

							Polling.prototype.poll = function () {
								debug("polling");
								this.polling = true;
								this.doPoll();
								this.emit("poll");
							};

							/**
							 * Overloads onData to detect payloads.
							 *
							 * @api private
							 */

							Polling.prototype.onData = function (data) {
								var self = this;
								debug("polling got data %s", data);
								var callback = function (packet, index, total) {
									// if its the first message we consider the transport open
									if ("opening" == self.readyState) {
										self.onOpen();
									}

									// if its a close packet, we close the ongoing requests
									if ("close" == packet.type) {
										self.onClose();
										return false;
									}

									// otherwise bypass onData and handle the message
									self.onPacket(packet);
								};

								// decode payload
								parser.decodePayload(data, this.socket.binaryType, callback);

								// if an event did not trigger closing
								if ("closed" != this.readyState) {
									// if we got data we're not polling
									this.polling = false;
									this.emit("pollComplete");

									if ("open" == this.readyState) {
										this.poll();
									} else {
										debug(
											'ignoring poll - transport state "%s"',
											this.readyState
										);
									}
								}
							};

							/**
							 * For polling, send a close packet.
							 *
							 * @api private
							 */

							Polling.prototype.doClose = function () {
								var self = this;

								function close() {
									debug("writing close packet");
									self.write([{ type: "close" }]);
								}

								if ("open" == this.readyState) {
									debug("transport open - closing");
									close();
								} else {
									// in case we're trying to close while
									// handshaking is in progress (GH-164)
									debug("transport not open - deferring close");
									this.once("open", close);
								}
							};

							/**
							 * Writes a packets payload.
							 *
							 * @param {Array} data packets
							 * @param {Function} drain callback
							 * @api private
							 */

							Polling.prototype.write = function (packets) {
								var self = this;
								this.writable = false;
								var callbackfn = function () {
									self.writable = true;
									self.emit("drain");
								};

								var self = this;
								parser.encodePayload(packets, this.supportsBinary, function (data) {
									self.doWrite(data, callbackfn);
								});
							};

							/**
							 * Generates uri for connection.
							 *
							 * @api private
							 */

							Polling.prototype.uri = function () {
								var query = this.query || {};
								var schema = this.secure ? "https" : "http";
								var port = "";

								// cache busting is forced
								if (false !== this.timestampRequests) {
									query[this.timestampParam] = yeast();
								}

								if (!this.supportsBinary && !query.sid) {
									query.b64 = 1;
								}

								query = parseqs.encode(query);

								// avoid port if default for schema
								if (
									this.port &&
									(("https" == schema && this.port != 443) ||
										("http" == schema && this.port != 80))
								) {
									port = ":" + this.port;
								}

								// prepend ? to query
								if (query.length) {
									query = "?" + query;
								}

								var ipv6 = this.hostname.indexOf(":") !== -1;
								return (
									schema +
									"://" +
									(ipv6 ? "[" + this.hostname + "]" : this.hostname) +
									port +
									this.path +
									query
								);
							};
						},
						{
							"../transport": 4,
							"component-inherit": 16,
							debug: 17,
							"engine.io-parser": 19,
							parseqs: 27,
							"xmlhttprequest-ssl": 10,
							yeast: 30
						}
					],

					9: [
						function (_dereq_, module, exports) {
							(function (global) {
								/**
								 * Module dependencies.
								 */

								var Transport = _dereq_("../transport");
								var parser = _dereq_("engine.io-parser");
								var parseqs = _dereq_("parseqs");
								var inherit = _dereq_("component-inherit");
								var yeast = _dereq_("yeast");
								var debug = _dereq_("debug")("engine.io-client:websocket");
								var BrowserWebSocket = global.WebSocket || global.MozWebSocket;

								/**
								 * Get either the `WebSocket` or `MozWebSocket` globals
								 * in the browser or try to resolve WebSocket-compatible
								 * interface exposed by `ws` for Node-like environment.
								 */

								var WebSocket = BrowserWebSocket;
								if (!WebSocket && typeof window === "undefined") {
									try {
										WebSocket = _dereq_("ws");
									} catch (e) {}
								}

								/**
								 * Module exports.
								 */

								module.exports = WS;

								/**
								 * WebSocket transport constructor.
								 *
								 * @api {Object} connection options
								 * @api public
								 */

								function WS(opts) {
									var forceBase64 = opts && opts.forceBase64;
									if (forceBase64) {
										this.supportsBinary = false;
									}
									this.perMessageDeflate = opts.perMessageDeflate;
									Transport.call(this, opts);
								}

								/**
								 * Inherits from Transport.
								 */

								inherit(WS, Transport);

								/**
								 * Transport name.
								 *
								 * @api public
								 */

								WS.prototype.name = "websocket";

								/*
								 * WebSockets support binary
								 */

								WS.prototype.supportsBinary = true;

								/**
								 * Opens socket.
								 *
								 * @api private
								 */

								WS.prototype.doOpen = function () {
									if (!this.check()) {
										// let probe timeout
										return;
									}

									var self = this;
									var uri = this.uri();
									var protocols = void 0;
									var opts = {
										agent: this.agent,
										perMessageDeflate: this.perMessageDeflate
									};

									// SSL options for Node.js client
									opts.pfx = this.pfx;
									opts.key = this.key;
									opts.passphrase = this.passphrase;
									opts.cert = this.cert;
									opts.ca = this.ca;
									opts.ciphers = this.ciphers;
									opts.rejectUnauthorized = this.rejectUnauthorized;
									if (this.extraHeaders) {
										opts.headers = this.extraHeaders;
									}

									this.ws = BrowserWebSocket
										? new WebSocket(uri)
										: new WebSocket(uri, protocols, opts);

									if (this.ws.binaryType === undefined) {
										this.supportsBinary = false;
									}

									if (this.ws.supports && this.ws.supports.binary) {
										this.supportsBinary = true;
										this.ws.binaryType = "buffer";
									} else {
										this.ws.binaryType = "arraybuffer";
									}

									this.addEventListeners();
								};

								/**
								 * Adds event listeners to the socket
								 *
								 * @api private
								 */

								WS.prototype.addEventListeners = function () {
									var self = this;

									this.ws.onopen = function () {
										self.onOpen();
									};
									this.ws.onclose = function () {
										self.onClose();
									};
									this.ws.onmessage = function (ev) {
										self.onData(ev.data);
									};
									this.ws.onerror = function (e) {
										self.onError("websocket error", e);
									};
								};

								/**
								 * Override `onData` to use a timer on iOS.
								 * See: https://gist.github.com/mloughran/2052006
								 *
								 * @api private
								 */

								if (
									"undefined" != typeof navigator &&
									/iPad|iPhone|iPod/i.test(navigator.userAgent)
								) {
									WS.prototype.onData = function (data) {
										var self = this;
										setTimeout(function () {
											Transport.prototype.onData.call(self, data);
										}, 0);
									};
								}

								/**
								 * Writes data to socket.
								 *
								 * @param {Array} array of packets.
								 * @api private
								 */

								WS.prototype.write = function (packets) {
									var self = this;
									this.writable = false;

									// encodePacket efficient as it uses WS framing
									// no need for encodePayload
									var total = packets.length;
									for (var i = 0, l = total; i < l; i++) {
										(function (packet) {
											parser.encodePacket(
												packet,
												self.supportsBinary,
												function (data) {
													if (!BrowserWebSocket) {
														// always create a new object (GH-437)
														var opts = {};
														if (packet.options) {
															opts.compress = packet.options.compress;
														}

														if (self.perMessageDeflate) {
															var len =
																"string" == typeof data
																	? global.Buffer.byteLength(data)
																	: data.length;
															if (
																len <
																self.perMessageDeflate.threshold
															) {
																opts.compress = false;
															}
														}
													}

													//Sometimes the websocket has already been closed but the browser didn't
													//have a chance of informing us about it yet, in that case send will
													//throw an error
													try {
														if (BrowserWebSocket) {
															// TypeError is thrown when passing the second argument on Safari
															self.ws.send(data);
														} else {
															self.ws.send(data, opts);
														}
													} catch (e) {
														debug(
															"websocket closed before onclose event"
														);
													}

													--total || done();
												}
											);
										})(packets[i]);
									}

									function done() {
										self.emit("flush");

										// fake drain
										// defer to next tick to allow Socket to clear writeBuffer
										setTimeout(function () {
											self.writable = true;
											self.emit("drain");
										}, 0);
									}
								};

								/**
								 * Called upon close
								 *
								 * @api private
								 */

								WS.prototype.onClose = function () {
									Transport.prototype.onClose.call(this);
								};

								/**
								 * Closes socket.
								 *
								 * @api private
								 */

								WS.prototype.doClose = function () {
									if (typeof this.ws !== "undefined") {
										this.ws.close();
									}
								};

								/**
								 * Generates uri for connection.
								 *
								 * @api private
								 */

								WS.prototype.uri = function () {
									var query = this.query || {};
									var schema = this.secure ? "wss" : "ws";
									var port = "";

									// avoid port if default for schema
									if (
										this.port &&
										(("wss" == schema && this.port != 443) ||
											("ws" == schema && this.port != 80))
									) {
										port = ":" + this.port;
									}

									// append timestamp to URI
									if (this.timestampRequests) {
										query[this.timestampParam] = yeast();
									}

									// communicate binary support capabilities
									if (!this.supportsBinary) {
										query.b64 = 1;
									}

									query = parseqs.encode(query);

									// prepend ? to query
									if (query.length) {
										query = "?" + query;
									}

									var ipv6 = this.hostname.indexOf(":") !== -1;
									return (
										schema +
										"://" +
										(ipv6 ? "[" + this.hostname + "]" : this.hostname) +
										port +
										this.path +
										query
									);
								};

								/**
								 * Feature detection for WebSocket.
								 *
								 * @return {Boolean} whether this transport is available.
								 * @api public
								 */

								WS.prototype.check = function () {
									return (
										!!WebSocket &&
										!(
											"__initialize" in WebSocket &&
											this.name === WS.prototype.name
										)
									);
								};
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{
							"../transport": 4,
							"component-inherit": 16,
							debug: 17,
							"engine.io-parser": 19,
							parseqs: 27,
							ws: undefined,
							yeast: 30
						}
					],

					10: [
						function (_dereq_, module, exports) {
							// browser shim for xmlhttprequest module
							var hasCORS = _dereq_("has-cors");

							module.exports = function (opts) {
								var xdomain = opts.xdomain;

								// scheme must be same when usign XDomainRequest
								// http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
								var xscheme = opts.xscheme;

								// XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.
								// https://github.com/Automattic/engine.io-client/pull/217
								var enablesXDR = opts.enablesXDR;

								// XMLHttpRequest can be disabled on IE
								try {
									if (
										"undefined" != typeof XMLHttpRequest &&
										(!xdomain || hasCORS)
									) {
										return new XMLHttpRequest();
									}
								} catch (e) {}

								// Use XDomainRequest for IE8 if enablesXDR is true
								// because loading bar keeps flashing when using jsonp-polling
								// https://github.com/yujiosaka/socke.io-ie8-loading-example
								try {
									if (
										"undefined" != typeof XDomainRequest &&
										!xscheme &&
										enablesXDR
									) {
										return new XDomainRequest();
									}
								} catch (e) {}

								if (!xdomain) {
									try {
										return new ActiveXObject("Microsoft.XMLHTTP");
									} catch (e) {}
								}
							};
						},
						{ "has-cors": 22 }
					],

					11: [
						function (_dereq_, module, exports) {
							module.exports = after;

							function after(count, callback, err_cb) {
								var bail = false;
								err_cb = err_cb || noop;
								proxy.count = count;

								return count === 0 ? callback() : proxy;

								function proxy(err, result) {
									if (proxy.count <= 0) {
										throw new Error("after called too many times");
									}
									--proxy.count;

									// after first error, rest are passed to err_cb
									if (err) {
										bail = true;
										callback(err);
										// future error callbacks will go to error handler
										callback = err_cb;
									} else if (proxy.count === 0 && !bail) {
										callback(null, result);
									}
								}
							}

							function noop() {}
						},
						{}
					],

					12: [
						function (_dereq_, module, exports) {
							/**
							 * An abstraction for slicing an arraybuffer even when
							 * ArrayBuffer.prototype.slice is not supported
							 *
							 * @api public
							 */

							module.exports = function (arraybuffer, start, end) {
								var bytes = arraybuffer.byteLength;
								start = start || 0;
								end = end || bytes;

								if (arraybuffer.slice) {
									return arraybuffer.slice(start, end);
								}

								if (start < 0) {
									start += bytes;
								}
								if (end < 0) {
									end += bytes;
								}
								if (end > bytes) {
									end = bytes;
								}

								if (start >= bytes || start >= end || bytes === 0) {
									return new ArrayBuffer(0);
								}

								var abv = new Uint8Array(arraybuffer);
								var result = new Uint8Array(end - start);
								for (var i = start, ii = 0; i < end; i++, ii++) {
									result[ii] = abv[i];
								}
								return result.buffer;
							};
						},
						{}
					],

					13: [
						function (_dereq_, module, exports) {
							/*
							 * base64-arraybuffer
							 * https://github.com/niklasvh/base64-arraybuffer
							 *
							 * Copyright (c) 2012 Niklas von Hertzen
							 * Licensed under the MIT license.
							 */
							(function (chars) {
								"use strict";

								exports.encode = function (arraybuffer) {
									var bytes = new Uint8Array(arraybuffer),
										i,
										len = bytes.length,
										base64 = "";

									for (i = 0; i < len; i += 3) {
										base64 += chars[bytes[i] >> 2];
										base64 +=
											chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
										base64 +=
											chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
										base64 += chars[bytes[i + 2] & 63];
									}

									if (len % 3 === 2) {
										base64 = base64.substring(0, base64.length - 1) + "=";
									} else if (len % 3 === 1) {
										base64 = base64.substring(0, base64.length - 2) + "==";
									}

									return base64;
								};

								exports.decode = function (base64) {
									var bufferLength = base64.length * 0.75,
										len = base64.length,
										i,
										p = 0,
										encoded1,
										encoded2,
										encoded3,
										encoded4;

									if (base64[base64.length - 1] === "=") {
										bufferLength--;
										if (base64[base64.length - 2] === "=") {
											bufferLength--;
										}
									}

									var arraybuffer = new ArrayBuffer(bufferLength),
										bytes = new Uint8Array(arraybuffer);

									for (i = 0; i < len; i += 4) {
										encoded1 = chars.indexOf(base64[i]);
										encoded2 = chars.indexOf(base64[i + 1]);
										encoded3 = chars.indexOf(base64[i + 2]);
										encoded4 = chars.indexOf(base64[i + 3]);

										bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
										bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
										bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
									}

									return arraybuffer;
								};
							})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
						},
						{}
					],

					14: [
						function (_dereq_, module, exports) {
							(function (global) {
								/**
								 * Create a blob builder even when vendor prefixes exist
								 */

								var BlobBuilder =
									global.BlobBuilder ||
									global.WebKitBlobBuilder ||
									global.MSBlobBuilder ||
									global.MozBlobBuilder;

								/**
								 * Check if Blob constructor is supported
								 */

								var blobSupported = (function () {
									try {
										var a = new Blob(["hi"]);
										return a.size === 2;
									} catch (e) {
										return false;
									}
								})();

								/**
								 * Check if Blob constructor supports ArrayBufferViews
								 * Fails in Safari 6, so we need to map to ArrayBuffers there.
								 */

								var blobSupportsArrayBufferView =
									blobSupported &&
									(function () {
										try {
											var b = new Blob([new Uint8Array([1, 2])]);
											return b.size === 2;
										} catch (e) {
											return false;
										}
									})();

								/**
								 * Check if BlobBuilder is supported
								 */

								var blobBuilderSupported =
									BlobBuilder &&
									BlobBuilder.prototype.append &&
									BlobBuilder.prototype.getBlob;

								/**
								 * Helper function that maps ArrayBufferViews to ArrayBuffers
								 * Used by BlobBuilder constructor and old browsers that didn't
								 * support it in the Blob constructor.
								 */

								function mapArrayBufferViews(ary) {
									for (var i = 0; i < ary.length; i++) {
										var chunk = ary[i];
										if (chunk.buffer instanceof ArrayBuffer) {
											var buf = chunk.buffer;

											// if this is a subarray, make a copy so we only
											// include the subarray region from the underlying buffer
											if (chunk.byteLength !== buf.byteLength) {
												var copy = new Uint8Array(chunk.byteLength);
												copy.set(
													new Uint8Array(
														buf,
														chunk.byteOffset,
														chunk.byteLength
													)
												);
												buf = copy.buffer;
											}

											ary[i] = buf;
										}
									}
								}

								function BlobBuilderConstructor(ary, options) {
									options = options || {};

									var bb = new BlobBuilder();
									mapArrayBufferViews(ary);

									for (var i = 0; i < ary.length; i++) {
										bb.append(ary[i]);
									}

									return options.type ? bb.getBlob(options.type) : bb.getBlob();
								}

								function BlobConstructor(ary, options) {
									mapArrayBufferViews(ary);
									return new Blob(ary, options || {});
								}

								module.exports = (function () {
									if (blobSupported) {
										return blobSupportsArrayBufferView
											? global.Blob
											: BlobConstructor;
									} else if (blobBuilderSupported) {
										return BlobBuilderConstructor;
									} else {
										return undefined;
									}
								})();
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{}
					],

					15: [
						function (_dereq_, module, exports) {
							/**
							 * Expose `Emitter`.
							 */

							module.exports = Emitter;

							/**
							 * Initialize a new `Emitter`.
							 *
							 * @api public
							 */

							function Emitter(obj) {
								if (obj) return mixin(obj);
							}

							/**
							 * Mixin the emitter properties.
							 *
							 * @param {Object} obj
							 * @return {Object}
							 * @api private
							 */

							function mixin(obj) {
								for (var key in Emitter.prototype) {
									obj[key] = Emitter.prototype[key];
								}
								return obj;
							}

							/**
							 * Listen on the given `event` with `fn`.
							 *
							 * @param {String} event
							 * @param {Function} fn
							 * @return {Emitter}
							 * @api public
							 */

							Emitter.prototype.on = Emitter.prototype.addEventListener = function (
								event,
								fn
							) {
								this._callbacks = this._callbacks || {};
								(this._callbacks[event] = this._callbacks[event] || []).push(fn);
								return this;
							};

							/**
							 * Adds an `event` listener that will be invoked a single
							 * time then automatically removed.
							 *
							 * @param {String} event
							 * @param {Function} fn
							 * @return {Emitter}
							 * @api public
							 */

							Emitter.prototype.once = function (event, fn) {
								var self = this;
								this._callbacks = this._callbacks || {};

								function on() {
									self.off(event, on);
									fn.apply(this, arguments);
								}

								on.fn = fn;
								this.on(event, on);
								return this;
							};

							/**
							 * Remove the given callback for `event` or all
							 * registered callbacks.
							 *
							 * @param {String} event
							 * @param {Function} fn
							 * @return {Emitter}
							 * @api public
							 */

							Emitter.prototype.off =
								Emitter.prototype.removeListener =
								Emitter.prototype.removeAllListeners =
								Emitter.prototype.removeEventListener =
									function (event, fn) {
										this._callbacks = this._callbacks || {};

										// all
										if (0 == arguments.length) {
											this._callbacks = {};
											return this;
										}

										// specific event
										var callbacks = this._callbacks[event];
										if (!callbacks) return this;

										// remove all handlers
										if (1 == arguments.length) {
											delete this._callbacks[event];
											return this;
										}

										// remove specific handler
										var cb;
										for (var i = 0; i < callbacks.length; i++) {
											cb = callbacks[i];
											if (cb === fn || cb.fn === fn) {
												callbacks.splice(i, 1);
												break;
											}
										}
										return this;
									};

							/**
							 * Emit `event` with the given args.
							 *
							 * @param {String} event
							 * @param {Mixed} ...
							 * @return {Emitter}
							 */

							Emitter.prototype.emit = function (event) {
								this._callbacks = this._callbacks || {};
								var args = [].slice.call(arguments, 1),
									callbacks = this._callbacks[event];

								if (callbacks) {
									callbacks = callbacks.slice(0);
									for (var i = 0, len = callbacks.length; i < len; ++i) {
										callbacks[i].apply(this, args);
									}
								}

								return this;
							};

							/**
							 * Return array of callbacks for `event`.
							 *
							 * @param {String} event
							 * @return {Array}
							 * @api public
							 */

							Emitter.prototype.listeners = function (event) {
								this._callbacks = this._callbacks || {};
								return this._callbacks[event] || [];
							};

							/**
							 * Check if this emitter has `event` handlers.
							 *
							 * @param {String} event
							 * @return {Boolean}
							 * @api public
							 */

							Emitter.prototype.hasListeners = function (event) {
								return !!this.listeners(event).length;
							};
						},
						{}
					],

					16: [
						function (_dereq_, module, exports) {
							module.exports = function (a, b) {
								var fn = function () {};
								fn.prototype = b.prototype;
								a.prototype = new fn();
								a.prototype.constructor = a;
							};
						},
						{}
					],

					17: [
						function (_dereq_, module, exports) {
							/**
							 * This is the web browser implementation of `debug()`.
							 *
							 * Expose `debug()` as the module.
							 */

							exports = module.exports = _dereq_("./debug");
							exports.log = log;
							exports.formatArgs = formatArgs;
							exports.save = save;
							exports.load = load;
							exports.useColors = useColors;
							exports.storage =
								"undefined" != typeof chrome && "undefined" != typeof chrome.storage
									? chrome.storage.local
									: localstorage();

							/**
							 * Colors.
							 */

							exports.colors = [
								"lightseagreen",
								"forestgreen",
								"goldenrod",
								"dodgerblue",
								"darkorchid",
								"crimson"
							];

							/**
							 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
							 * and the Firebug extension (any Firefox version) are known
							 * to support "%c" CSS customizations.
							 *
							 * TODO: add a `localStorage` variable to explicitly enable/disable colors
							 */

							function useColors() {
								// is webkit? http://stackoverflow.com/a/16459606/376773
								return (
									"WebkitAppearance" in document.documentElement.style ||
									// is firebug? http://stackoverflow.com/a/398120/376773
									(window.console &&
										(console.firebug ||
											(console.exception && console.table))) ||
									// is firefox >= v31?
									// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
									(navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) &&
										parseInt(RegExp.$1, 10) >= 31)
								);
							}

							/**
							 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
							 */

							exports.formatters.j = function (v) {
								return JSON.stringify(v);
							};

							/**
							 * Colorize log arguments if enabled.
							 *
							 * @api public
							 */

							function formatArgs() {
								var args = arguments;
								var useColors = this.useColors;

								args[0] =
									(useColors ? "%c" : "") +
									this.namespace +
									(useColors ? " %c" : " ") +
									args[0] +
									(useColors ? "%c " : " ") +
									"+" +
									exports.humanize(this.diff);

								if (!useColors) return args;

								var c = "color: " + this.color;
								args = [args[0], c, "color: inherit"].concat(
									Array.prototype.slice.call(args, 1)
								);

								// the final "%c" is somewhat tricky, because there could be other
								// arguments passed either before or after the %c, so we need to
								// figure out the correct index to insert the CSS into
								var index = 0;
								var lastC = 0;
								args[0].replace(/%[a-z%]/g, function (match) {
									if ("%%" === match) return;
									index++;
									if ("%c" === match) {
										// we only are interested in the *last* %c
										// (the user may have provided their own)
										lastC = index;
									}
								});

								args.splice(lastC, 0, c);
								return args;
							}

							/**
							 * Invokes `console.log()` when available.
							 * No-op when `console.log` is not a "function".
							 *
							 * @api public
							 */

							function log() {
								// this hackery is required for IE8/9, where
								// the `console.log` function doesn't have 'apply'
								return (
									"object" === typeof console &&
									console.log &&
									Function.prototype.apply.call(console.log, console, arguments)
								);
							}

							/**
							 * Save `namespaces`.
							 *
							 * @param {String} namespaces
							 * @api private
							 */

							function save(namespaces) {
								try {
									if (null == namespaces) {
										exports.storage.removeItem("debug");
									} else {
										exports.storage.debug = namespaces;
									}
								} catch (e) {}
							}

							/**
							 * Load `namespaces`.
							 *
							 * @return {String} returns the previously persisted debug modes
							 * @api private
							 */

							function load() {
								var r;
								try {
									r = exports.storage.debug;
								} catch (e) {}
								return r;
							}

							/**
							 * Enable namespaces listed in `localStorage.debug` initially.
							 */

							exports.enable(load());

							/**
							 * Localstorage attempts to return the localstorage.
							 *
							 * This is necessary because safari throws
							 * when a user disables cookies/localstorage
							 * and you attempt to access it.
							 *
							 * @return {LocalStorage}
							 * @api private
							 */

							function localstorage() {
								try {
									return window.localStorage;
								} catch (e) {}
							}
						},
						{ "./debug": 18 }
					],

					18: [
						function (_dereq_, module, exports) {
							/**
							 * This is the common logic for both the Node.js and web browser
							 * implementations of `debug()`.
							 *
							 * Expose `debug()` as the module.
							 */

							exports = module.exports = debug;
							exports.coerce = coerce;
							exports.disable = disable;
							exports.enable = enable;
							exports.enabled = enabled;
							exports.humanize = _dereq_("ms");

							/**
							 * The currently active debug mode names, and names to skip.
							 */

							exports.names = [];
							exports.skips = [];

							/**
							 * Map of special "%n" handling functions, for the debug "format" argument.
							 *
							 * Valid key names are a single, lowercased letter, i.e. "n".
							 */

							exports.formatters = {};

							/**
							 * Previously assigned color.
							 */

							var prevColor = 0;

							/**
							 * Previous log timestamp.
							 */

							var prevTime;

							/**
							 * Select a color.
							 *
							 * @return {Number}
							 * @api private
							 */

							function selectColor() {
								return exports.colors[prevColor++ % exports.colors.length];
							}

							/**
							 * Create a debugger with the given `namespace`.
							 *
							 * @param {String} namespace
							 * @return {Function}
							 * @api public
							 */

							function debug(namespace) {
								// define the `disabled` version
								function disabled() {}

								disabled.enabled = false;

								// define the `enabled` version
								function enabled() {
									var self = enabled;

									// set `diff` timestamp
									var curr = +new Date();
									var ms = curr - (prevTime || curr);
									self.diff = ms;
									self.prev = prevTime;
									self.curr = curr;
									prevTime = curr;

									// add the `color` if not set
									if (null == self.useColors)
										self.useColors = exports.useColors();
									if (null == self.color && self.useColors)
										self.color = selectColor();

									var args = Array.prototype.slice.call(arguments);

									args[0] = exports.coerce(args[0]);

									if ("string" !== typeof args[0]) {
										// anything else let's inspect with %o
										args = ["%o"].concat(args);
									}

									// apply any `formatters` transformations
									var index = 0;
									args[0] = args[0].replace(
										/%([a-z%])/g,
										function (match, format) {
											// if we encounter an escaped % then don't increase the array index
											if (match === "%%") return match;
											index++;
											var formatter = exports.formatters[format];
											if ("function" === typeof formatter) {
												var val = args[index];
												match = formatter.call(self, val);

												// now we need to remove `args[index]` since it's inlined in the `format`
												args.splice(index, 1);
												index--;
											}
											return match;
										}
									);

									if ("function" === typeof exports.formatArgs) {
										args = exports.formatArgs.apply(self, args);
									}
									var logFn =
										enabled.log || exports.log || console.log.bind(console);
									logFn.apply(self, args);
								}

								enabled.enabled = true;

								var fn = exports.enabled(namespace) ? enabled : disabled;

								fn.namespace = namespace;

								return fn;
							}

							/**
							 * Enables a debug mode by namespaces. This can include modes
							 * separated by a colon and wildcards.
							 *
							 * @param {String} namespaces
							 * @api public
							 */

							function enable(namespaces) {
								exports.save(namespaces);

								var split = (namespaces || "").split(/[\s,]+/);
								var len = split.length;

								for (var i = 0; i < len; i++) {
									if (!split[i]) continue; // ignore empty strings
									namespaces = split[i].replace(/\*/g, ".*?");
									if (namespaces[0] === "-") {
										exports.skips.push(
											new RegExp("^" + namespaces.substr(1) + "$")
										);
									} else {
										exports.names.push(new RegExp("^" + namespaces + "$"));
									}
								}
							}

							/**
							 * Disable debug output.
							 *
							 * @api public
							 */

							function disable() {
								exports.enable("");
							}

							/**
							 * Returns true if the given mode name is enabled, false otherwise.
							 *
							 * @param {String} name
							 * @return {Boolean}
							 * @api public
							 */

							function enabled(name) {
								var i, len;
								for (i = 0, len = exports.skips.length; i < len; i++) {
									if (exports.skips[i].test(name)) {
										return false;
									}
								}
								for (i = 0, len = exports.names.length; i < len; i++) {
									if (exports.names[i].test(name)) {
										return true;
									}
								}
								return false;
							}

							/**
							 * Coerce `val`.
							 *
							 * @param {Mixed} val
							 * @return {Mixed}
							 * @api private
							 */

							function coerce(val) {
								if (val instanceof Error) return val.stack || val.message;
								return val;
							}
						},
						{ ms: 25 }
					],

					19: [
						function (_dereq_, module, exports) {
							(function (global) {
								/**
								 * Module dependencies.
								 */

								var keys = _dereq_("./keys");
								var hasBinary = _dereq_("has-binary");
								var sliceBuffer = _dereq_("arraybuffer.slice");
								var base64encoder = _dereq_("base64-arraybuffer");
								var after = _dereq_("after");
								var utf8 = _dereq_("utf8");

								/**
								 * Check if we are running an android browser. That requires us to use
								 * ArrayBuffer with polling transports...
								 *
								 * http://ghinda.net/jpeg-blob-ajax-android/
								 */

								var isAndroid = navigator.userAgent.match(/Android/i);

								/**
								 * Check if we are running in PhantomJS.
								 * Uploading a Blob with PhantomJS does not work correctly, as reported here:
								 * https://github.com/ariya/phantomjs/issues/11395
								 * @type boolean
								 */
								var isPhantomJS = /PhantomJS/i.test(navigator.userAgent);

								/**
								 * When true, avoids using Blobs to encode payloads.
								 * @type boolean
								 */
								var dontSendBlobs = isAndroid || isPhantomJS;

								/**
								 * Current protocol version.
								 */

								exports.protocol = 3;

								/**
								 * Packet types.
								 */

								var packets = (exports.packets = {
									open: 0, // non-ws
									close: 1, // non-ws
									ping: 2,
									pong: 3,
									message: 4,
									upgrade: 5,
									noop: 6
								});

								var packetslist = keys(packets);

								/**
								 * Premade error packet.
								 */

								var err = { type: "error", data: "parser error" };

								/**
								 * Create a blob api even for blob builder when vendor prefixes exist
								 */

								var Blob = _dereq_("blob");

								/**
								 * Encodes a packet.
								 *
								 *     <packet type id> [ <data> ]
								 *
								 * Example:
								 *
								 *     5hello world
								 *     3
								 *     4
								 *
								 * Binary is encoded in an identical principle
								 *
								 * @api private
								 */

								exports.encodePacket = function (
									packet,
									supportsBinary,
									utf8encode,
									callback
								) {
									if ("function" == typeof supportsBinary) {
										callback = supportsBinary;
										supportsBinary = false;
									}

									if ("function" == typeof utf8encode) {
										callback = utf8encode;
										utf8encode = null;
									}

									var data =
										packet.data === undefined
											? undefined
											: packet.data.buffer || packet.data;

									if (global.ArrayBuffer && data instanceof ArrayBuffer) {
										return encodeArrayBuffer(packet, supportsBinary, callback);
									} else if (Blob && data instanceof global.Blob) {
										return encodeBlob(packet, supportsBinary, callback);
									}

									// might be an object with { base64: true, data: dataAsBase64String }
									if (data && data.base64) {
										return encodeBase64Object(packet, callback);
									}

									// Sending data as a utf-8 string
									var encoded = packets[packet.type];

									// data fragment is optional
									if (undefined !== packet.data) {
										encoded += utf8encode
											? utf8.encode(String(packet.data))
											: String(packet.data);
									}

									return callback("" + encoded);
								};

								function encodeBase64Object(packet, callback) {
									// packet data is an object { base64: true, data: dataAsBase64String }
									var message =
										"b" + exports.packets[packet.type] + packet.data.data;
									return callback(message);
								}

								/**
								 * Encode packet helpers for binary types
								 */

								function encodeArrayBuffer(packet, supportsBinary, callback) {
									if (!supportsBinary) {
										return exports.encodeBase64Packet(packet, callback);
									}

									var data = packet.data;
									var contentArray = new Uint8Array(data);
									var resultBuffer = new Uint8Array(1 + data.byteLength);

									resultBuffer[0] = packets[packet.type];
									for (var i = 0; i < contentArray.length; i++) {
										resultBuffer[i + 1] = contentArray[i];
									}

									return callback(resultBuffer.buffer);
								}

								function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {
									if (!supportsBinary) {
										return exports.encodeBase64Packet(packet, callback);
									}

									var fr = new FileReader();
									fr.onload = function () {
										packet.data = fr.result;
										exports.encodePacket(
											packet,
											supportsBinary,
											true,
											callback
										);
									};
									return fr.readAsArrayBuffer(packet.data);
								}

								function encodeBlob(packet, supportsBinary, callback) {
									if (!supportsBinary) {
										return exports.encodeBase64Packet(packet, callback);
									}

									if (dontSendBlobs) {
										return encodeBlobAsArrayBuffer(
											packet,
											supportsBinary,
											callback
										);
									}

									var length = new Uint8Array(1);
									length[0] = packets[packet.type];
									var blob = new Blob([length.buffer, packet.data]);

									return callback(blob);
								}

								/**
								 * Encodes a packet with binary data in a base64 string
								 *
								 * @param {Object} packet, has `type` and `data`
								 * @return {String} base64 encoded message
								 */

								exports.encodeBase64Packet = function (packet, callback) {
									var message = "b" + exports.packets[packet.type];
									if (Blob && packet.data instanceof global.Blob) {
										var fr = new FileReader();
										fr.onload = function () {
											var b64 = fr.result.split(",")[1];
											callback(message + b64);
										};
										return fr.readAsDataURL(packet.data);
									}

									var b64data;
									try {
										b64data = String.fromCharCode.apply(
											null,
											new Uint8Array(packet.data)
										);
									} catch (e) {
										// iPhone Safari doesn't let you apply with typed arrays
										var typed = new Uint8Array(packet.data);
										var basic = new Array(typed.length);
										for (var i = 0; i < typed.length; i++) {
											basic[i] = typed[i];
										}
										b64data = String.fromCharCode.apply(null, basic);
									}
									message += global.btoa(b64data);
									return callback(message);
								};

								/**
								 * Decodes a packet. Changes format to Blob if requested.
								 *
								 * @return {Object} with `type` and `data` (if any)
								 * @api private
								 */

								exports.decodePacket = function (data, binaryType, utf8decode) {
									// String data
									if (typeof data == "string" || data === undefined) {
										if (data.charAt(0) == "b") {
											return exports.decodeBase64Packet(
												data.substr(1),
												binaryType
											);
										}

										if (utf8decode) {
											try {
												data = utf8.decode(data);
											} catch (e) {
												return err;
											}
										}
										var type = data.charAt(0);

										if (Number(type) != type || !packetslist[type]) {
											return err;
										}

										if (data.length > 1) {
											return {
												type: packetslist[type],
												data: data.substring(1)
											};
										} else {
											return { type: packetslist[type] };
										}
									}

									var asArray = new Uint8Array(data);
									var type = asArray[0];
									var rest = sliceBuffer(data, 1);
									if (Blob && binaryType === "blob") {
										rest = new Blob([rest]);
									}
									return { type: packetslist[type], data: rest };
								};

								/**
								 * Decodes a packet encoded in a base64 string
								 *
								 * @param {String} base64 encoded message
								 * @return {Object} with `type` and `data` (if any)
								 */

								exports.decodeBase64Packet = function (msg, binaryType) {
									var type = packetslist[msg.charAt(0)];
									if (!global.ArrayBuffer) {
										return {
											type: type,
											data: { base64: true, data: msg.substr(1) }
										};
									}

									var data = base64encoder.decode(msg.substr(1));

									if (binaryType === "blob" && Blob) {
										data = new Blob([data]);
									}

									return { type: type, data: data };
								};

								/**
								 * Encodes multiple messages (payload).
								 *
								 *     <length>:data
								 *
								 * Example:
								 *
								 *     11:hello world2:hi
								 *
								 * If any contents are binary, they will be encoded as base64 strings. Base64
								 * encoded strings are marked with a b before the length specifier
								 *
								 * @param {Array} packets
								 * @api private
								 */

								exports.encodePayload = function (
									packets,
									supportsBinary,
									callback
								) {
									if (typeof supportsBinary == "function") {
										callback = supportsBinary;
										supportsBinary = null;
									}

									var isBinary = hasBinary(packets);

									if (supportsBinary && isBinary) {
										if (Blob && !dontSendBlobs) {
											return exports.encodePayloadAsBlob(packets, callback);
										}

										return exports.encodePayloadAsArrayBuffer(
											packets,
											callback
										);
									}

									if (!packets.length) {
										return callback("0:");
									}

									function setLengthHeader(message) {
										return message.length + ":" + message;
									}

									function encodeOne(packet, doneCallback) {
										exports.encodePacket(
											packet,
											!isBinary ? false : supportsBinary,
											true,
											function (message) {
												doneCallback(null, setLengthHeader(message));
											}
										);
									}

									map(packets, encodeOne, function (err, results) {
										return callback(results.join(""));
									});
								};

								/**
								 * Async array map using after
								 */

								function map(ary, each, done) {
									var result = new Array(ary.length);
									var next = after(ary.length, done);

									var eachWithIndex = function (i, el, cb) {
										each(el, function (error, msg) {
											result[i] = msg;
											cb(error, result);
										});
									};

									for (var i = 0; i < ary.length; i++) {
										eachWithIndex(i, ary[i], next);
									}
								}

								/*
								 * Decodes data when a payload is maybe expected. Possible binary contents are
								 * decoded from their base64 representation
								 *
								 * @param {String} data, callback method
								 * @api public
								 */

								exports.decodePayload = function (data, binaryType, callback) {
									if (typeof data != "string") {
										return exports.decodePayloadAsBinary(
											data,
											binaryType,
											callback
										);
									}

									if (typeof binaryType === "function") {
										callback = binaryType;
										binaryType = null;
									}

									var packet;
									if (data == "") {
										// parser error - ignoring payload
										return callback(err, 0, 1);
									}

									var length = "",
										n,
										msg;

									for (var i = 0, l = data.length; i < l; i++) {
										var chr = data.charAt(i);

										if (":" != chr) {
											length += chr;
										} else {
											if ("" == length || length != (n = Number(length))) {
												// parser error - ignoring payload
												return callback(err, 0, 1);
											}

											msg = data.substr(i + 1, n);

											if (length != msg.length) {
												// parser error - ignoring payload
												return callback(err, 0, 1);
											}

											if (msg.length) {
												packet = exports.decodePacket(
													msg,
													binaryType,
													true
												);

												if (
													err.type == packet.type &&
													err.data == packet.data
												) {
													// parser error in individual packet - ignoring payload
													return callback(err, 0, 1);
												}

												var ret = callback(packet, i + n, l);
												if (false === ret) return;
											}

											// advance cursor
											i += n;
											length = "";
										}
									}

									if (length != "") {
										// parser error - ignoring payload
										return callback(err, 0, 1);
									}
								};

								/**
								 * Encodes multiple messages (payload) as binary.
								 *
								 * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number
								 * 255><data>
								 *
								 * Example:
								 * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers
								 *
								 * @param {Array} packets
								 * @return {ArrayBuffer} encoded payload
								 * @api private
								 */

								exports.encodePayloadAsArrayBuffer = function (packets, callback) {
									if (!packets.length) {
										return callback(new ArrayBuffer(0));
									}

									function encodeOne(packet, doneCallback) {
										exports.encodePacket(packet, true, true, function (data) {
											return doneCallback(null, data);
										});
									}

									map(packets, encodeOne, function (err, encodedPackets) {
										var totalLength = encodedPackets.reduce(function (acc, p) {
											var len;
											if (typeof p === "string") {
												len = p.length;
											} else {
												len = p.byteLength;
											}
											return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2
										}, 0);

										var resultArray = new Uint8Array(totalLength);

										var bufferIndex = 0;
										encodedPackets.forEach(function (p) {
											var isString = typeof p === "string";
											var ab = p;
											if (isString) {
												var view = new Uint8Array(p.length);
												for (var i = 0; i < p.length; i++) {
													view[i] = p.charCodeAt(i);
												}
												ab = view.buffer;
											}

											if (isString) {
												// not true binary
												resultArray[bufferIndex++] = 0;
											} else {
												// true binary
												resultArray[bufferIndex++] = 1;
											}

											var lenStr = ab.byteLength.toString();
											for (var i = 0; i < lenStr.length; i++) {
												resultArray[bufferIndex++] = parseInt(lenStr[i]);
											}
											resultArray[bufferIndex++] = 255;

											var view = new Uint8Array(ab);
											for (var i = 0; i < view.length; i++) {
												resultArray[bufferIndex++] = view[i];
											}
										});

										return callback(resultArray.buffer);
									});
								};

								/**
								 * Encode as Blob
								 */

								exports.encodePayloadAsBlob = function (packets, callback) {
									function encodeOne(packet, doneCallback) {
										exports.encodePacket(
											packet,
											true,
											true,
											function (encoded) {
												var binaryIdentifier = new Uint8Array(1);
												binaryIdentifier[0] = 1;
												if (typeof encoded === "string") {
													var view = new Uint8Array(encoded.length);
													for (var i = 0; i < encoded.length; i++) {
														view[i] = encoded.charCodeAt(i);
													}
													encoded = view.buffer;
													binaryIdentifier[0] = 0;
												}

												var len =
													encoded instanceof ArrayBuffer
														? encoded.byteLength
														: encoded.size;

												var lenStr = len.toString();
												var lengthAry = new Uint8Array(lenStr.length + 1);
												for (var i = 0; i < lenStr.length; i++) {
													lengthAry[i] = parseInt(lenStr[i]);
												}
												lengthAry[lenStr.length] = 255;

												if (Blob) {
													var blob = new Blob([
														binaryIdentifier.buffer,
														lengthAry.buffer,
														encoded
													]);
													doneCallback(null, blob);
												}
											}
										);
									}

									map(packets, encodeOne, function (err, results) {
										return callback(new Blob(results));
									});
								};

								/*
								 * Decodes data when a payload is maybe expected. Strings are decoded by
								 * interpreting each byte as a key code for entries marked to start with 0. See
								 * description of encodePayloadAsBinary
								 *
								 * @param {ArrayBuffer} data, callback method
								 * @api public
								 */

								exports.decodePayloadAsBinary = function (
									data,
									binaryType,
									callback
								) {
									if (typeof binaryType === "function") {
										callback = binaryType;
										binaryType = null;
									}

									var bufferTail = data;
									var buffers = [];

									var numberTooLong = false;
									while (bufferTail.byteLength > 0) {
										var tailArray = new Uint8Array(bufferTail);
										var isString = tailArray[0] === 0;
										var msgLength = "";

										for (var i = 1; ; i++) {
											if (tailArray[i] == 255) break;

											if (msgLength.length > 310) {
												numberTooLong = true;
												break;
											}

											msgLength += tailArray[i];
										}

										if (numberTooLong) return callback(err, 0, 1);

										bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);
										msgLength = parseInt(msgLength);

										var msg = sliceBuffer(bufferTail, 0, msgLength);
										if (isString) {
											try {
												msg = String.fromCharCode.apply(
													null,
													new Uint8Array(msg)
												);
											} catch (e) {
												// iPhone Safari doesn't let you apply to typed arrays
												var typed = new Uint8Array(msg);
												msg = "";
												for (var i = 0; i < typed.length; i++) {
													msg += String.fromCharCode(typed[i]);
												}
											}
										}

										buffers.push(msg);
										bufferTail = sliceBuffer(bufferTail, msgLength);
									}

									var total = buffers.length;
									buffers.forEach(function (buffer, i) {
										callback(
											exports.decodePacket(buffer, binaryType, true),
											i,
											total
										);
									});
								};
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{
							"./keys": 20,
							after: 11,
							"arraybuffer.slice": 12,
							"base64-arraybuffer": 13,
							blob: 14,
							"has-binary": 21,
							utf8: 29
						}
					],

					20: [
						function (_dereq_, module, exports) {
							/**
							 * Gets the keys for an object.
							 *
							 * @return {Array} keys
							 * @api private
							 */

							module.exports =
								Object.keys ||
								function keys(obj) {
									var arr = [];
									var has = Object.prototype.hasOwnProperty;

									for (var i in obj) {
										if (has.call(obj, i)) {
											arr.push(i);
										}
									}
									return arr;
								};
						},
						{}
					],

					21: [
						function (_dereq_, module, exports) {
							(function (global) {
								/*
								 * Module requirements.
								 */

								var isArray = _dereq_("isarray");

								/**
								 * Module exports.
								 */

								module.exports = hasBinary;

								/**
								 * Checks for binary data.
								 *
								 * Right now only Buffer and ArrayBuffer are supported..
								 *
								 * @param {Object} anything
								 * @api public
								 */

								function hasBinary(data) {
									function _hasBinary(obj) {
										if (!obj) return false;

										if (
											(global.Buffer && global.Buffer.isBuffer(obj)) ||
											(global.ArrayBuffer && obj instanceof ArrayBuffer) ||
											(global.Blob && obj instanceof Blob) ||
											(global.File && obj instanceof File)
										) {
											return true;
										}

										if (isArray(obj)) {
											for (var i = 0; i < obj.length; i++) {
												if (_hasBinary(obj[i])) {
													return true;
												}
											}
										} else if (obj && "object" == typeof obj) {
											if (obj.toJSON) {
												obj = obj.toJSON();
											}

											for (var key in obj) {
												if (
													Object.prototype.hasOwnProperty.call(
														obj,
														key
													) &&
													_hasBinary(obj[key])
												) {
													return true;
												}
											}
										}

										return false;
									}

									return _hasBinary(data);
								}
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{ isarray: 24 }
					],

					22: [
						function (_dereq_, module, exports) {
							/**
							 * Module exports.
							 *
							 * Logic borrowed from Modernizr:
							 *
							 *   - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js
							 */

							try {
								module.exports =
									typeof XMLHttpRequest !== "undefined" &&
									"withCredentials" in new XMLHttpRequest();
							} catch (err) {
								// if XMLHttp support is disabled in IE then it will throw
								// when trying to create
								module.exports = false;
							}
						},
						{}
					],

					23: [
						function (_dereq_, module, exports) {
							var indexOf = [].indexOf;

							module.exports = function (arr, obj) {
								if (indexOf) return arr.indexOf(obj);
								for (var i = 0; i < arr.length; ++i) {
									if (arr[i] === obj) return i;
								}
								return -1;
							};
						},
						{}
					],

					24: [
						function (_dereq_, module, exports) {
							module.exports =
								Array.isArray ||
								function (arr) {
									return Object.prototype.toString.call(arr) == "[object Array]";
								};
						},
						{}
					],

					25: [
						function (_dereq_, module, exports) {
							/**
							 * Helpers.
							 */

							var s = 1000;
							var m = s * 60;
							var h = m * 60;
							var d = h * 24;
							var y = d * 365.25;

							/**
							 * Parse or format the given `val`.
							 *
							 * Options:
							 *
							 *  - `long` verbose formatting [false]
							 *
							 * @param {String|Number} val
							 * @param {Object} options
							 * @return {String|Number}
							 * @api public
							 */

							module.exports = function (val, options) {
								options = options || {};
								if ("string" == typeof val) return parse(val);
								return options.long ? long(val) : short(val);
							};

							/**
							 * Parse the given `str` and return milliseconds.
							 *
							 * @param {String} str
							 * @return {Number}
							 * @api private
							 */

							function parse(str) {
								str = "" + str;
								if (str.length > 10000) return;
								var match =
									/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
										str
									);
								if (!match) return;
								var n = parseFloat(match[1]);
								var type = (match[2] || "ms").toLowerCase();
								switch (type) {
									case "years":
									case "year":
									case "yrs":
									case "yr":
									case "y":
										return n * y;
									case "days":
									case "day":
									case "d":
										return n * d;
									case "hours":
									case "hour":
									case "hrs":
									case "hr":
									case "h":
										return n * h;
									case "minutes":
									case "minute":
									case "mins":
									case "min":
									case "m":
										return n * m;
									case "seconds":
									case "second":
									case "secs":
									case "sec":
									case "s":
										return n * s;
									case "milliseconds":
									case "millisecond":
									case "msecs":
									case "msec":
									case "ms":
										return n;
								}
							}

							/**
							 * Short format for `ms`.
							 *
							 * @param {Number} ms
							 * @return {String}
							 * @api private
							 */

							function short(ms) {
								if (ms >= d) return Math.round(ms / d) + "d";
								if (ms >= h) return Math.round(ms / h) + "h";
								if (ms >= m) return Math.round(ms / m) + "m";
								if (ms >= s) return Math.round(ms / s) + "s";
								return ms + "ms";
							}

							/**
							 * Long format for `ms`.
							 *
							 * @param {Number} ms
							 * @return {String}
							 * @api private
							 */

							function long(ms) {
								return (
									plural(ms, d, "day") ||
									plural(ms, h, "hour") ||
									plural(ms, m, "minute") ||
									plural(ms, s, "second") ||
									ms + " ms"
								);
							}

							/**
							 * Pluralization helper.
							 */

							function plural(ms, n, name) {
								if (ms < n) return;
								if (ms < n * 1.5) return Math.floor(ms / n) + " " + name;
								return Math.ceil(ms / n) + " " + name + "s";
							}
						},
						{}
					],

					26: [
						function (_dereq_, module, exports) {
							(function (global) {
								/**
								 * JSON parse.
								 *
								 * @see Based on jQuery#parseJSON (MIT) and JSON2
								 * @api private
								 */

								var rvalidchars = /^[\],:{}\s]*$/;
								var rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
								var rvalidtokens =
									/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
								var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g;
								var rtrimLeft = /^\s+/;
								var rtrimRight = /\s+$/;

								module.exports = function parsejson(data) {
									if ("string" != typeof data || !data) {
										return null;
									}

									data = data.replace(rtrimLeft, "").replace(rtrimRight, "");

									// Attempt to parse using the native JSON parser first
									if (global.JSON && JSON.parse) {
										return JSON.parse(data);
									}

									if (
										rvalidchars.test(
											data
												.replace(rvalidescape, "@")
												.replace(rvalidtokens, "]")
												.replace(rvalidbraces, "")
										)
									) {
										return new Function("return " + data)();
									}
								};
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{}
					],

					27: [
						function (_dereq_, module, exports) {
							/**
							 * Compiles a querystring
							 * Returns string representation of the object
							 *
							 * @param {Object}
							 * @api private
							 */

							exports.encode = function (obj) {
								var str = "";

								for (var i in obj) {
									if (obj.hasOwnProperty(i)) {
										if (str.length) str += "&";
										str +=
											encodeURIComponent(i) +
											"=" +
											encodeURIComponent(obj[i]);
									}
								}

								return str;
							};

							/**
							 * Parses a simple querystring into an object
							 *
							 * @param {String} qs
							 * @api private
							 */

							exports.decode = function (qs) {
								var qry = {};
								var pairs = qs.split("&");
								for (var i = 0, l = pairs.length; i < l; i++) {
									var pair = pairs[i].split("=");
									qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
								}
								return qry;
							};
						},
						{}
					],

					28: [
						function (_dereq_, module, exports) {
							/**
							 * Parses an URI
							 *
							 * @author Steven Levithan <stevenlevithan.com> (MIT license)
							 * @api private
							 */

							var re =
								/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;

							var parts = [
								"source",
								"protocol",
								"authority",
								"userInfo",
								"user",
								"password",
								"host",
								"port",
								"relative",
								"path",
								"directory",
								"file",
								"query",
								"anchor"
							];

							module.exports = function parseuri(str) {
								var src = str,
									b = str.indexOf("["),
									e = str.indexOf("]");

								if (b != -1 && e != -1) {
									str =
										str.substring(0, b) +
										str.substring(b, e).replace(/:/g, ";") +
										str.substring(e, str.length);
								}

								var m = re.exec(str || ""),
									uri = {},
									i = 14;

								while (i--) {
									uri[parts[i]] = m[i] || "";
								}

								if (b != -1 && e != -1) {
									uri.source = src;
									uri.host = uri.host
										.substring(1, uri.host.length - 1)
										.replace(/;/g, ":");
									uri.authority = uri.authority
										.replace("[", "")
										.replace("]", "")
										.replace(/;/g, ":");
									uri.ipv6uri = true;
								}

								return uri;
							};
						},
						{}
					],

					29: [
						function (_dereq_, module, exports) {
							(function (global) {
								/*! https://mths.be/utf8js v2.0.0 by @mathias */
								(function (root) {
									// Detect free variables `exports`
									var freeExports = typeof exports == "object" && exports;

									// Detect free variable `module`
									var freeModule =
										typeof module == "object" &&
										module &&
										module.exports == freeExports &&
										module;

									// Detect free variable `global`, from Node.js or Browserified code,
									// and use it as `root`
									var freeGlobal = typeof global == "object" && global;
									if (
										freeGlobal.global === freeGlobal ||
										freeGlobal.window === freeGlobal
									) {
										root = freeGlobal;
									}

									/*--------------------------------------------------------------------------*/

									var stringFromCharCode = String.fromCharCode;

									// Taken from https://mths.be/punycode
									function ucs2decode(string) {
										var output = [];
										var counter = 0;
										var length = string.length;
										var value;
										var extra;
										while (counter < length) {
											value = string.charCodeAt(counter++);
											if (
												value >= 0xd800 &&
												value <= 0xdbff &&
												counter < length
											) {
												// high surrogate, and there is a next character
												extra = string.charCodeAt(counter++);
												if ((extra & 0xfc00) == 0xdc00) {
													// low surrogate
													output.push(
														((value & 0x3ff) << 10) +
															(extra & 0x3ff) +
															0x10000
													);
												} else {
													// unmatched surrogate; only append this code unit, in case the next
													// code unit is the high surrogate of a surrogate pair
													output.push(value);
													counter--;
												}
											} else {
												output.push(value);
											}
										}
										return output;
									}

									// Taken from https://mths.be/punycode
									function ucs2encode(array) {
										var length = array.length;
										var index = -1;
										var value;
										var output = "";
										while (++index < length) {
											value = array[index];
											if (value > 0xffff) {
												value -= 0x10000;
												output += stringFromCharCode(
													((value >>> 10) & 0x3ff) | 0xd800
												);
												value = 0xdc00 | (value & 0x3ff);
											}
											output += stringFromCharCode(value);
										}
										return output;
									}

									function checkScalarValue(codePoint) {
										if (codePoint >= 0xd800 && codePoint <= 0xdfff) {
											throw Error(
												"Lone surrogate U+" +
													codePoint.toString(16).toUpperCase() +
													" is not a scalar value"
											);
										}
									}

									/*--------------------------------------------------------------------------*/

									function createByte(codePoint, shift) {
										return stringFromCharCode(
											((codePoint >> shift) & 0x3f) | 0x80
										);
									}

									function encodeCodePoint(codePoint) {
										if ((codePoint & 0xffffff80) == 0) {
											// 1-byte sequence
											return stringFromCharCode(codePoint);
										}
										var symbol = "";
										if ((codePoint & 0xfffff800) == 0) {
											// 2-byte sequence
											symbol = stringFromCharCode(
												((codePoint >> 6) & 0x1f) | 0xc0
											);
										} else if ((codePoint & 0xffff0000) == 0) {
											// 3-byte sequence
											checkScalarValue(codePoint);
											symbol = stringFromCharCode(
												((codePoint >> 12) & 0x0f) | 0xe0
											);
											symbol += createByte(codePoint, 6);
										} else if ((codePoint & 0xffe00000) == 0) {
											// 4-byte sequence
											symbol = stringFromCharCode(
												((codePoint >> 18) & 0x07) | 0xf0
											);
											symbol += createByte(codePoint, 12);
											symbol += createByte(codePoint, 6);
										}
										symbol += stringFromCharCode((codePoint & 0x3f) | 0x80);
										return symbol;
									}

									function utf8encode(string) {
										var codePoints = ucs2decode(string);
										var length = codePoints.length;
										var index = -1;
										var codePoint;
										var byteString = "";
										while (++index < length) {
											codePoint = codePoints[index];
											byteString += encodeCodePoint(codePoint);
										}
										return byteString;
									}

									/*--------------------------------------------------------------------------*/

									function readContinuationByte() {
										if (byteIndex >= byteCount) {
											throw Error("Invalid byte index");
										}

										var continuationByte = byteArray[byteIndex] & 0xff;
										byteIndex++;

										if ((continuationByte & 0xc0) == 0x80) {
											return continuationByte & 0x3f;
										}

										// If we end up here, it’s not a continuation byte
										throw Error("Invalid continuation byte");
									}

									function decodeSymbol() {
										var byte1;
										var byte2;
										var byte3;
										var byte4;
										var codePoint;

										if (byteIndex > byteCount) {
											throw Error("Invalid byte index");
										}

										if (byteIndex == byteCount) {
											return false;
										}

										// Read first byte
										byte1 = byteArray[byteIndex] & 0xff;
										byteIndex++;

										// 1-byte sequence (no continuation bytes)
										if ((byte1 & 0x80) == 0) {
											return byte1;
										}

										// 2-byte sequence
										if ((byte1 & 0xe0) == 0xc0) {
											var byte2 = readContinuationByte();
											codePoint = ((byte1 & 0x1f) << 6) | byte2;
											if (codePoint >= 0x80) {
												return codePoint;
											} else {
												throw Error("Invalid continuation byte");
											}
										}

										// 3-byte sequence (may include unpaired surrogates)
										if ((byte1 & 0xf0) == 0xe0) {
											byte2 = readContinuationByte();
											byte3 = readContinuationByte();
											codePoint =
												((byte1 & 0x0f) << 12) | (byte2 << 6) | byte3;
											if (codePoint >= 0x0800) {
												checkScalarValue(codePoint);
												return codePoint;
											} else {
												throw Error("Invalid continuation byte");
											}
										}

										// 4-byte sequence
										if ((byte1 & 0xf8) == 0xf0) {
											byte2 = readContinuationByte();
											byte3 = readContinuationByte();
											byte4 = readContinuationByte();
											codePoint =
												((byte1 & 0x0f) << 0x12) |
												(byte2 << 0x0c) |
												(byte3 << 0x06) |
												byte4;
											if (codePoint >= 0x010000 && codePoint <= 0x10ffff) {
												return codePoint;
											}
										}

										throw Error("Invalid UTF-8 detected");
									}

									var byteArray;
									var byteCount;
									var byteIndex;

									function utf8decode(byteString) {
										byteArray = ucs2decode(byteString);
										byteCount = byteArray.length;
										byteIndex = 0;
										var codePoints = [];
										var tmp;
										while ((tmp = decodeSymbol()) !== false) {
											codePoints.push(tmp);
										}
										return ucs2encode(codePoints);
									}

									/*--------------------------------------------------------------------------*/

									var utf8 = {
										version: "2.0.0",
										encode: utf8encode,
										decode: utf8decode
									};

									// Some AMD build optimizers, like r.js, check for specific condition patterns
									// like the following:
									if (
										typeof define == "function" &&
										typeof define.amd == "object" &&
										define.amd
									) {
										define(function () {
											return utf8;
										});
									} else if (freeExports && !freeExports.nodeType) {
										if (freeModule) {
											// in Node.js or RingoJS v0.8.0+
											freeModule.exports = utf8;
										} else {
											// in Narwhal or RingoJS v0.7.0-
											var object = {};
											var hasOwnProperty = object.hasOwnProperty;
											for (var key in utf8) {
												hasOwnProperty.call(utf8, key) &&
													(freeExports[key] = utf8[key]);
											}
										}
									} else {
										// in Rhino or a web browser
										root.utf8 = utf8;
									}
								})(this);
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{}
					],

					30: [
						function (_dereq_, module, exports) {
							"use strict";

							var alphabet =
									"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".split(
										""
									),
								length = 64,
								map = {},
								seed = 0,
								i = 0,
								prev;

							/**
							 * Return a string representing the specified number.
							 *
							 * @param {Number} num The number to convert.
							 * @returns {String} The string representation of the number.
							 * @api public
							 */
							function encode(num) {
								var encoded = "";

								do {
									encoded = alphabet[num % length] + encoded;
									num = Math.floor(num / length);
								} while (num > 0);

								return encoded;
							}

							/**
							 * Return the integer value specified by the given string.
							 *
							 * @param {String} str The string to convert.
							 * @returns {Number} The integer value represented by the string.
							 * @api public
							 */
							function decode(str) {
								var decoded = 0;

								for (i = 0; i < str.length; i++) {
									decoded = decoded * length + map[str.charAt(i)];
								}

								return decoded;
							}

							/**
							 * Yeast: A tiny growing id generator.
							 *
							 * @returns {String} A unique id.
							 * @api public
							 */
							function yeast() {
								var now = encode(+new Date());

								if (now !== prev) return ((seed = 0), (prev = now));
								return now + "." + encode(seed++);
							}

							//
							// Map each character to its index.
							//
							for (; i < length; i++) map[alphabet[i]] = i;

							//
							// Expose the `yeast`, `encode` and `decode` functions.
							//
							yeast.encode = encode;
							yeast.decode = decode;
							module.exports = yeast;
						},
						{}
					],

					31: [
						function (_dereq_, module, exports) {
							/**
							 * Module dependencies.
							 */

							var url = _dereq_("./url");
							var parser = _dereq_("socket.io-parser");
							var Manager = _dereq_("./manager");
							var debug = _dereq_("debug")("socket.io-client");

							/**
							 * Module exports.
							 */

							module.exports = exports = lookup;

							/**
							 * Managers cache.
							 */

							var cache = (exports.managers = {});

							/**
							 * Looks up an existing `Manager` for multiplexing.
							 * If the user summons:
							 *
							 *   `io('http://localhost/a');`
							 *   `io('http://localhost/b');`
							 *
							 * We reuse the existing instance based on same scheme/port/host,
							 * and we initialize sockets for each namespace.
							 *
							 * @api public
							 */

							function lookup(uri, opts) {
								if (typeof uri == "object") {
									opts = uri;
									uri = undefined;
								}

								opts = opts || {};

								var parsed = url(uri);
								var source = parsed.source;
								var id = parsed.id;
								var path = parsed.path;
								var sameNamespace = cache[id] && path in cache[id].nsps;
								var newConnection =
									opts.forceNew ||
									opts["force new connection"] ||
									false === opts.multiplex ||
									sameNamespace;

								var io;

								if (newConnection) {
									debug("ignoring socket cache for %s", source);
									io = Manager(source, opts);
								} else {
									if (!cache[id]) {
										debug("new io instance for %s", source);
										cache[id] = Manager(source, opts);
									}
									io = cache[id];
								}

								return io.socket(parsed.path);
							}

							/**
							 * Protocol version.
							 *
							 * @api public
							 */

							exports.protocol = parser.protocol;

							/**
							 * `connect`.
							 *
							 * @param {String} uri
							 * @api public
							 */

							exports.connect = lookup;

							/**
							 * Expose constructors for standalone build.
							 *
							 * @api public
							 */

							exports.Manager = _dereq_("./manager");
							exports.Socket = _dereq_("./socket");
						},
						{
							"./manager": 32,
							"./socket": 34,
							"./url": 35,
							debug: 39,
							"socket.io-parser": 47
						}
					],

					32: [
						function (_dereq_, module, exports) {
							/**
							 * Module dependencies.
							 */

							var eio = _dereq_("engine.io-client");
							var Socket = _dereq_("./socket");
							var Emitter = _dereq_("component-emitter");
							var parser = _dereq_("socket.io-parser");
							var on = _dereq_("./on");
							var bind = _dereq_("component-bind");
							var debug = _dereq_("debug")("socket.io-client:manager");
							var indexOf = _dereq_("indexof");
							var Backoff = _dereq_("backo2");

							/**
							 * IE6+ hasOwnProperty
							 */

							var has = Object.prototype.hasOwnProperty;

							/**
							 * Module exports
							 */

							module.exports = Manager;

							/**
							 * `Manager` constructor.
							 *
							 * @param {String} engine instance or engine uri/opts
							 * @param {Object} options
							 * @api public
							 */

							function Manager(uri, opts) {
								if (!(this instanceof Manager)) return new Manager(uri, opts);
								if (uri && "object" == typeof uri) {
									opts = uri;
									uri = undefined;
								}
								opts = opts || {};

								opts.path = opts.path || "/socket.io";
								this.nsps = {};
								this.subs = [];
								this.opts = opts;
								this.reconnection(opts.reconnection !== false);
								this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
								this.reconnectionDelay(opts.reconnectionDelay || 1000);
								this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
								this.randomizationFactor(opts.randomizationFactor || 0.5);
								this.backoff = new Backoff({
									min: this.reconnectionDelay(),
									max: this.reconnectionDelayMax(),
									jitter: this.randomizationFactor()
								});
								this.timeout(null == opts.timeout ? 20000 : opts.timeout);
								this.readyState = "closed";
								this.uri = uri;
								this.connecting = [];
								this.lastPing = null;
								this.encoding = false;
								this.packetBuffer = [];
								this.encoder = new parser.Encoder();
								this.decoder = new parser.Decoder();
								this.autoConnect = opts.autoConnect !== false;
								if (this.autoConnect) this.open();
							}

							/**
							 * Propagate given event to sockets and emit on `this`
							 *
							 * @api private
							 */

							Manager.prototype.emitAll = function () {
								this.emit.apply(this, arguments);
								for (var nsp in this.nsps) {
									if (has.call(this.nsps, nsp)) {
										this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);
									}
								}
							};

							/**
							 * Update `socket.id` of all sockets
							 *
							 * @api private
							 */

							Manager.prototype.updateSocketIds = function () {
								for (var nsp in this.nsps) {
									if (has.call(this.nsps, nsp)) {
										this.nsps[nsp].id = this.engine.id;
									}
								}
							};

							/**
							 * Mix in `Emitter`.
							 */

							Emitter(Manager.prototype);

							/**
							 * Sets the `reconnection` config.
							 *
							 * @param {Boolean} true/false if it should automatically reconnect
							 * @return {Manager} self or value
							 * @api public
							 */

							Manager.prototype.reconnection = function (v) {
								if (!arguments.length) return this._reconnection;
								this._reconnection = !!v;
								return this;
							};

							/**
							 * Sets the reconnection attempts config.
							 *
							 * @param {Number} max reconnection attempts before giving up
							 * @return {Manager} self or value
							 * @api public
							 */

							Manager.prototype.reconnectionAttempts = function (v) {
								if (!arguments.length) return this._reconnectionAttempts;
								this._reconnectionAttempts = v;
								return this;
							};

							/**
							 * Sets the delay between reconnections.
							 *
							 * @param {Number} delay
							 * @return {Manager} self or value
							 * @api public
							 */

							Manager.prototype.reconnectionDelay = function (v) {
								if (!arguments.length) return this._reconnectionDelay;
								this._reconnectionDelay = v;
								this.backoff && this.backoff.setMin(v);
								return this;
							};

							Manager.prototype.randomizationFactor = function (v) {
								if (!arguments.length) return this._randomizationFactor;
								this._randomizationFactor = v;
								this.backoff && this.backoff.setJitter(v);
								return this;
							};

							/**
							 * Sets the maximum delay between reconnections.
							 *
							 * @param {Number} delay
							 * @return {Manager} self or value
							 * @api public
							 */

							Manager.prototype.reconnectionDelayMax = function (v) {
								if (!arguments.length) return this._reconnectionDelayMax;
								this._reconnectionDelayMax = v;
								this.backoff && this.backoff.setMax(v);
								return this;
							};

							/**
							 * Sets the connection timeout. `false` to disable
							 *
							 * @return {Manager} self or value
							 * @api public
							 */

							Manager.prototype.timeout = function (v) {
								if (!arguments.length) return this._timeout;
								this._timeout = v;
								return this;
							};

							/**
							 * Starts trying to reconnect if reconnection is enabled and we have not
							 * started reconnecting yet
							 *
							 * @api private
							 */

							Manager.prototype.maybeReconnectOnOpen = function () {
								// Only try to reconnect if it's the first time we're connecting
								if (
									!this.reconnecting &&
									this._reconnection &&
									this.backoff.attempts === 0
								) {
									// keeps reconnection from firing twice for the same reconnection loop
									this.reconnect();
								}
							};

							/**
							 * Sets the current transport `socket`.
							 *
							 * @param {Function} optional, callback
							 * @return {Manager} self
							 * @api public
							 */

							Manager.prototype.open = Manager.prototype.connect = function (fn) {
								debug("readyState %s", this.readyState);
								if (~this.readyState.indexOf("open")) return this;

								debug("opening %s", this.uri);
								this.engine = eio(this.uri, this.opts);
								var socket = this.engine;
								var self = this;
								this.readyState = "opening";
								this.skipReconnect = false;

								// emit `open`
								var openSub = on(socket, "open", function () {
									self.onopen();
									fn && fn();
								});

								// emit `connect_error`
								var errorSub = on(socket, "error", function (data) {
									debug("connect_error");
									self.cleanup();
									self.readyState = "closed";
									self.emitAll("connect_error", data);
									if (fn) {
										var err = new Error("Connection error");
										err.data = data;
										fn(err);
									} else {
										// Only do this if there is no fn to handle the error
										self.maybeReconnectOnOpen();
									}
								});

								// emit `connect_timeout`
								if (false !== this._timeout) {
									var timeout = this._timeout;
									debug("connect attempt will timeout after %d", timeout);

									// set timer
									var timer = setTimeout(function () {
										debug("connect attempt timed out after %d", timeout);
										openSub.destroy();
										socket.close();
										socket.emit("error", "timeout");
										self.emitAll("connect_timeout", timeout);
									}, timeout);

									this.subs.push({
										destroy: function () {
											clearTimeout(timer);
										}
									});
								}

								this.subs.push(openSub);
								this.subs.push(errorSub);

								return this;
							};

							/**
							 * Called upon transport open.
							 *
							 * @api private
							 */

							Manager.prototype.onopen = function () {
								debug("open");

								// clear old subs
								this.cleanup();

								// mark as open
								this.readyState = "open";
								this.emit("open");

								// add new subs
								var socket = this.engine;
								this.subs.push(on(socket, "data", bind(this, "ondata")));
								this.subs.push(on(socket, "ping", bind(this, "onping")));
								this.subs.push(on(socket, "pong", bind(this, "onpong")));
								this.subs.push(on(socket, "error", bind(this, "onerror")));
								this.subs.push(on(socket, "close", bind(this, "onclose")));
								this.subs.push(
									on(this.decoder, "decoded", bind(this, "ondecoded"))
								);
							};

							/**
							 * Called upon a ping.
							 *
							 * @api private
							 */

							Manager.prototype.onping = function () {
								this.lastPing = new Date();
								this.emitAll("ping");
							};

							/**
							 * Called upon a packet.
							 *
							 * @api private
							 */

							Manager.prototype.onpong = function () {
								this.emitAll("pong", new Date() - this.lastPing);
							};

							/**
							 * Called with data.
							 *
							 * @api private
							 */

							Manager.prototype.ondata = function (data) {
								this.decoder.add(data);
							};

							/**
							 * Called when parser fully decodes a packet.
							 *
							 * @api private
							 */

							Manager.prototype.ondecoded = function (packet) {
								this.emit("packet", packet);
							};

							/**
							 * Called upon socket error.
							 *
							 * @api private
							 */

							Manager.prototype.onerror = function (err) {
								debug("error", err);
								this.emitAll("error", err);
							};

							/**
							 * Creates a new socket for the given `nsp`.
							 *
							 * @return {Socket}
							 * @api public
							 */

							Manager.prototype.socket = function (nsp) {
								var socket = this.nsps[nsp];
								if (!socket) {
									socket = new Socket(this, nsp);
									this.nsps[nsp] = socket;
									var self = this;
									socket.on("connecting", onConnecting);
									socket.on("connect", function () {
										socket.id = self.engine.id;
									});

									if (this.autoConnect) {
										// manually call here since connecting evnet is fired before listening
										onConnecting();
									}
								}

								function onConnecting() {
									if (!~indexOf(self.connecting, socket)) {
										self.connecting.push(socket);
									}
								}

								return socket;
							};

							/**
							 * Called upon a socket close.
							 *
							 * @param {Socket} socket
							 */

							Manager.prototype.destroy = function (socket) {
								var index = indexOf(this.connecting, socket);
								if (~index) this.connecting.splice(index, 1);
								if (this.connecting.length) return;

								this.close();
							};

							/**
							 * Writes a packet.
							 *
							 * @param {Object} packet
							 * @api private
							 */

							Manager.prototype.packet = function (packet) {
								debug("writing packet %j", packet);
								var self = this;

								if (!self.encoding) {
									// encode, then write to engine with result
									self.encoding = true;
									this.encoder.encode(packet, function (encodedPackets) {
										for (var i = 0; i < encodedPackets.length; i++) {
											self.engine.write(encodedPackets[i], packet.options);
										}
										self.encoding = false;
										self.processPacketQueue();
									});
								} else {
									// add packet to the queue
									self.packetBuffer.push(packet);
								}
							};

							/**
							 * If packet buffer is non-empty, begins encoding the
							 * next packet in line.
							 *
							 * @api private
							 */

							Manager.prototype.processPacketQueue = function () {
								if (this.packetBuffer.length > 0 && !this.encoding) {
									var pack = this.packetBuffer.shift();
									this.packet(pack);
								}
							};

							/**
							 * Clean up transport subscriptions and packet buffer.
							 *
							 * @api private
							 */

							Manager.prototype.cleanup = function () {
								debug("cleanup");

								var sub;
								while ((sub = this.subs.shift())) sub.destroy();

								this.packetBuffer = [];
								this.encoding = false;
								this.lastPing = null;

								this.decoder.destroy();
							};

							/**
							 * Close the current socket.
							 *
							 * @api private
							 */

							Manager.prototype.close = Manager.prototype.disconnect = function () {
								debug("disconnect");
								this.skipReconnect = true;
								this.reconnecting = false;
								if ("opening" == this.readyState) {
									// `onclose` will not fire because
									// an open event never happened
									this.cleanup();
								}
								this.backoff.reset();
								this.readyState = "closed";
								if (this.engine) this.engine.close();
							};

							/**
							 * Called upon engine close.
							 *
							 * @api private
							 */

							Manager.prototype.onclose = function (reason) {
								debug("onclose");

								this.cleanup();
								this.backoff.reset();
								this.readyState = "closed";
								this.emit("close", reason);

								if (this._reconnection && !this.skipReconnect) {
									this.reconnect();
								}
							};

							/**
							 * Attempt a reconnection.
							 *
							 * @api private
							 */

							Manager.prototype.reconnect = function () {
								if (this.reconnecting || this.skipReconnect) return this;

								var self = this;

								if (this.backoff.attempts >= this._reconnectionAttempts) {
									debug("reconnect failed");
									this.backoff.reset();
									this.emitAll("reconnect_failed");
									this.reconnecting = false;
								} else {
									var delay = this.backoff.duration();
									debug("will wait %dms before reconnect attempt", delay);

									this.reconnecting = true;
									var timer = setTimeout(function () {
										if (self.skipReconnect) return;

										debug("attempting reconnect");
										self.emitAll("reconnect_attempt", self.backoff.attempts);
										self.emitAll("reconnecting", self.backoff.attempts);

										// check again for the case socket closed in above events
										if (self.skipReconnect) return;

										self.open(function (err) {
											if (err) {
												debug("reconnect attempt error");
												self.reconnecting = false;
												self.reconnect();
												self.emitAll("reconnect_error", err.data);
											} else {
												debug("reconnect success");
												self.onreconnect();
											}
										});
									}, delay);

									this.subs.push({
										destroy: function () {
											clearTimeout(timer);
										}
									});
								}
							};

							/**
							 * Called upon successful reconnect.
							 *
							 * @api private
							 */

							Manager.prototype.onreconnect = function () {
								var attempt = this.backoff.attempts;
								this.reconnecting = false;
								this.backoff.reset();
								this.updateSocketIds();
								this.emitAll("reconnect", attempt);
							};
						},
						{
							"./on": 33,
							"./socket": 34,
							backo2: 36,
							"component-bind": 37,
							"component-emitter": 38,
							debug: 39,
							"engine.io-client": 1,
							indexof: 42,
							"socket.io-parser": 47
						}
					],

					33: [
						function (_dereq_, module, exports) {
							/**
							 * Module exports.
							 */

							module.exports = on;

							/**
							 * Helper for subscriptions.
							 *
							 * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`
							 * @param {String} event name
							 * @param {Function} callback
							 * @api public
							 */

							function on(obj, ev, fn) {
								obj.on(ev, fn);
								return {
									destroy: function () {
										obj.removeListener(ev, fn);
									}
								};
							}
						},
						{}
					],

					34: [
						function (_dereq_, module, exports) {
							/**
							 * Module dependencies.
							 */

							var parser = _dereq_("socket.io-parser");
							var Emitter = _dereq_("component-emitter");
							var toArray = _dereq_("to-array");
							var on = _dereq_("./on");
							var bind = _dereq_("component-bind");
							var debug = _dereq_("debug")("socket.io-client:socket");
							var hasBin = _dereq_("has-binary");

							/**
							 * Module exports.
							 */

							module.exports = exports = Socket;

							/**
							 * Internal events (blacklisted).
							 * These events can't be emitted by the user.
							 *
							 * @api private
							 */

							var events = {
								connect: 1,
								connect_error: 1,
								connect_timeout: 1,
								connecting: 1,
								disconnect: 1,
								error: 1,
								reconnect: 1,
								reconnect_attempt: 1,
								reconnect_failed: 1,
								reconnect_error: 1,
								reconnecting: 1,
								ping: 1,
								pong: 1
							};

							/**
							 * Shortcut to `Emitter#emit`.
							 */

							var emit = Emitter.prototype.emit;

							/**
							 * `Socket` constructor.
							 *
							 * @api public
							 */

							function Socket(io, nsp) {
								this.io = io;
								this.nsp = nsp;
								this.json = this; // compat
								this.ids = 0;
								this.acks = {};
								this.receiveBuffer = [];
								this.sendBuffer = [];
								this.connected = false;
								this.disconnected = true;
								if (this.io.autoConnect) this.open();
							}

							/**
							 * Mix in `Emitter`.
							 */

							Emitter(Socket.prototype);

							/**
							 * Subscribe to open, close and packet events
							 *
							 * @api private
							 */

							Socket.prototype.subEvents = function () {
								if (this.subs) return;

								var io = this.io;
								this.subs = [
									on(io, "open", bind(this, "onopen")),
									on(io, "packet", bind(this, "onpacket")),
									on(io, "close", bind(this, "onclose"))
								];
							};

							/**
							 * "Opens" the socket.
							 *
							 * @api public
							 */

							Socket.prototype.open = Socket.prototype.connect = function () {
								if (this.connected) return this;

								this.subEvents();
								this.io.open(); // ensure open
								if ("open" == this.io.readyState) this.onopen();
								this.emit("connecting");
								return this;
							};

							/**
							 * Sends a `message` event.
							 *
							 * @return {Socket} self
							 * @api public
							 */

							Socket.prototype.send = function () {
								var args = toArray(arguments);
								args.unshift("message");
								this.emit.apply(this, args);
								return this;
							};

							/**
							 * Override `emit`.
							 * If the event is in `events`, it's emitted normally.
							 *
							 * @param {String} event name
							 * @return {Socket} self
							 * @api public
							 */

							Socket.prototype.emit = function (ev) {
								if (events.hasOwnProperty(ev)) {
									emit.apply(this, arguments);
									return this;
								}

								var args = toArray(arguments);
								var parserType = parser.EVENT; // default
								if (hasBin(args)) {
									parserType = parser.BINARY_EVENT;
								} // binary
								var packet = { type: parserType, data: args };

								packet.options = {};
								packet.options.compress =
									!this.flags || false !== this.flags.compress;

								// event ack callback
								if ("function" == typeof args[args.length - 1]) {
									debug("emitting packet with ack id %d", this.ids);
									this.acks[this.ids] = args.pop();
									packet.id = this.ids++;
								}

								if (this.connected) {
									this.packet(packet);
								} else {
									this.sendBuffer.push(packet);
								}

								delete this.flags;

								return this;
							};

							/**
							 * Sends a packet.
							 *
							 * @param {Object} packet
							 * @api private
							 */

							Socket.prototype.packet = function (packet) {
								packet.nsp = this.nsp;
								this.io.packet(packet);
							};

							/**
							 * Called upon engine `open`.
							 *
							 * @api private
							 */

							Socket.prototype.onopen = function () {
								debug("transport is open - connecting");

								// write connect packet if necessary
								if ("/" != this.nsp) {
									this.packet({ type: parser.CONNECT });
								}
							};

							/**
							 * Called upon engine `close`.
							 *
							 * @param {String} reason
							 * @api private
							 */

							Socket.prototype.onclose = function (reason) {
								debug("close (%s)", reason);
								this.connected = false;
								this.disconnected = true;
								delete this.id;
								this.emit("disconnect", reason);
							};

							/**
							 * Called with socket packet.
							 *
							 * @param {Object} packet
							 * @api private
							 */

							Socket.prototype.onpacket = function (packet) {
								if (packet.nsp != this.nsp) return;

								switch (packet.type) {
									case parser.CONNECT:
										this.onconnect();
										break;

									case parser.EVENT:
										this.onevent(packet);
										break;

									case parser.BINARY_EVENT:
										this.onevent(packet);
										break;

									case parser.ACK:
										this.onack(packet);
										break;

									case parser.BINARY_ACK:
										this.onack(packet);
										break;

									case parser.DISCONNECT:
										this.ondisconnect();
										break;

									case parser.ERROR:
										this.emit("error", packet.data);
										break;
								}
							};

							/**
							 * Called upon a server event.
							 *
							 * @param {Object} packet
							 * @api private
							 */

							Socket.prototype.onevent = function (packet) {
								var args = packet.data || [];
								debug("emitting event %j", args);

								if (null != packet.id) {
									debug("attaching ack callback to event");
									args.push(this.ack(packet.id));
								}

								if (this.connected) {
									emit.apply(this, args);
								} else {
									this.receiveBuffer.push(args);
								}
							};

							/**
							 * Produces an ack callback to emit with an event.
							 *
							 * @api private
							 */

							Socket.prototype.ack = function (id) {
								var self = this;
								var sent = false;
								return function () {
									// prevent double callbacks
									if (sent) return;
									sent = true;
									var args = toArray(arguments);
									debug("sending ack %j", args);

									var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
									self.packet({
										type: type,
										id: id,
										data: args
									});
								};
							};

							/**
							 * Called upon a server acknowlegement.
							 *
							 * @param {Object} packet
							 * @api private
							 */

							Socket.prototype.onack = function (packet) {
								var ack = this.acks[packet.id];
								if ("function" == typeof ack) {
									debug("calling ack %s with %j", packet.id, packet.data);
									ack.apply(this, packet.data);
									delete this.acks[packet.id];
								} else {
									debug("bad ack %s", packet.id);
								}
							};

							/**
							 * Called upon server connect.
							 *
							 * @api private
							 */

							Socket.prototype.onconnect = function () {
								this.connected = true;
								this.disconnected = false;
								this.emit("connect");
								this.emitBuffered();
							};

							/**
							 * Emit buffered events (received and emitted).
							 *
							 * @api private
							 */

							Socket.prototype.emitBuffered = function () {
								var i;
								for (i = 0; i < this.receiveBuffer.length; i++) {
									emit.apply(this, this.receiveBuffer[i]);
								}
								this.receiveBuffer = [];

								for (i = 0; i < this.sendBuffer.length; i++) {
									this.packet(this.sendBuffer[i]);
								}
								this.sendBuffer = [];
							};

							/**
							 * Called upon server disconnect.
							 *
							 * @api private
							 */

							Socket.prototype.ondisconnect = function () {
								debug("server disconnect (%s)", this.nsp);
								this.destroy();
								this.onclose("io server disconnect");
							};

							/**
							 * Called upon forced client/server side disconnections,
							 * this method ensures the manager stops tracking us and
							 * that reconnections don't get triggered for this.
							 *
							 * @api private.
							 */

							Socket.prototype.destroy = function () {
								if (this.subs) {
									// clean subscriptions to avoid reconnections
									for (var i = 0; i < this.subs.length; i++) {
										this.subs[i].destroy();
									}
									this.subs = null;
								}

								this.io.destroy(this);
							};

							/**
							 * Disconnects the socket manually.
							 *
							 * @return {Socket} self
							 * @api public
							 */

							Socket.prototype.close = Socket.prototype.disconnect = function () {
								if (this.connected) {
									debug("performing disconnect (%s)", this.nsp);
									this.packet({ type: parser.DISCONNECT });
								}

								// remove socket from pool
								this.destroy();

								if (this.connected) {
									// fire events
									this.onclose("io client disconnect");
								}
								return this;
							};

							/**
							 * Sets the compress flag.
							 *
							 * @param {Boolean} if `true`, compresses the sending data
							 * @return {Socket} self
							 * @api public
							 */

							Socket.prototype.compress = function (compress) {
								this.flags = this.flags || {};
								this.flags.compress = compress;
								return this;
							};
						},
						{
							"./on": 33,
							"component-bind": 37,
							"component-emitter": 38,
							debug: 39,
							"has-binary": 41,
							"socket.io-parser": 47,
							"to-array": 51
						}
					],

					35: [
						function (_dereq_, module, exports) {
							(function (global) {
								/**
								 * Module dependencies.
								 */

								var parseuri = _dereq_("parseuri");
								var debug = _dereq_("debug")("socket.io-client:url");

								/**
								 * Module exports.
								 */

								module.exports = url;

								/**
								 * URL parser.
								 *
								 * @param {String} url
								 * @param {Object} An object meant to mimic window.location.
								 *                 Defaults to window.location.
								 * @api public
								 */

								function url(uri, loc) {
									var obj = uri;

									// default to window.location
									var loc = loc || global.location;
									if (null == uri) uri = loc.protocol + "//" + loc.host;

									// relative path support
									if ("string" == typeof uri) {
										if ("/" == uri.charAt(0)) {
											if ("/" == uri.charAt(1)) {
												uri = loc.protocol + uri;
											} else {
												uri = loc.host + uri;
											}
										}

										if (!/^(https?|wss?):\/\//.test(uri)) {
											debug("protocol-less url %s", uri);
											if ("undefined" != typeof loc) {
												uri = loc.protocol + "//" + uri;
											} else {
												uri = "https://" + uri;
											}
										}

										// parse
										debug("parse %s", uri);
										obj = parseuri(uri);
									}

									// make sure we treat `localhost:80` and `localhost` equally
									if (!obj.port) {
										if (/^(http|ws)$/.test(obj.protocol)) {
											obj.port = "80";
										} else if (/^(http|ws)s$/.test(obj.protocol)) {
											obj.port = "443";
										}
									}

									obj.path = obj.path || "/";

									var ipv6 = obj.host.indexOf(":") !== -1;
									var host = ipv6 ? "[" + obj.host + "]" : obj.host;

									// define unique id
									obj.id = obj.protocol + "://" + host + ":" + obj.port;
									// define href
									obj.href =
										obj.protocol +
										"://" +
										host +
										(loc && loc.port == obj.port ? "" : ":" + obj.port);

									return obj;
								}
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{ debug: 39, parseuri: 45 }
					],

					36: [
						function (_dereq_, module, exports) {
							/**
							 * Expose `Backoff`.
							 */

							module.exports = Backoff;

							/**
							 * Initialize backoff timer with `opts`.
							 *
							 * - `min` initial timeout in milliseconds [100]
							 * - `max` max timeout [10000]
							 * - `jitter` [0]
							 * - `factor` [2]
							 *
							 * @param {Object} opts
							 * @api public
							 */

							function Backoff(opts) {
								opts = opts || {};
								this.ms = opts.min || 100;
								this.max = opts.max || 10000;
								this.factor = opts.factor || 2;
								this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;
								this.attempts = 0;
							}

							/**
							 * Return the backoff duration.
							 *
							 * @return {Number}
							 * @api public
							 */

							Backoff.prototype.duration = function () {
								var ms = this.ms * Math.pow(this.factor, this.attempts++);
								if (this.jitter) {
									var rand = Math.random();
									var deviation = Math.floor(rand * this.jitter * ms);
									ms =
										(Math.floor(rand * 10) & 1) == 0
											? ms - deviation
											: ms + deviation;
								}
								return Math.min(ms, this.max) | 0;
							};

							/**
							 * Reset the number of attempts.
							 *
							 * @api public
							 */

							Backoff.prototype.reset = function () {
								this.attempts = 0;
							};

							/**
							 * Set the minimum duration
							 *
							 * @api public
							 */

							Backoff.prototype.setMin = function (min) {
								this.ms = min;
							};

							/**
							 * Set the maximum duration
							 *
							 * @api public
							 */

							Backoff.prototype.setMax = function (max) {
								this.max = max;
							};

							/**
							 * Set the jitter
							 *
							 * @api public
							 */

							Backoff.prototype.setJitter = function (jitter) {
								this.jitter = jitter;
							};
						},
						{}
					],

					37: [
						function (_dereq_, module, exports) {
							/**
							 * Slice reference.
							 */

							var slice = [].slice;

							/**
							 * Bind `obj` to `fn`.
							 *
							 * @param {Object} obj
							 * @param {Function|String} fn or string
							 * @return {Function}
							 * @api public
							 */

							module.exports = function (obj, fn) {
								if ("string" == typeof fn) fn = obj[fn];
								if ("function" != typeof fn)
									throw new Error("bind() requires a function");
								var args = slice.call(arguments, 2);
								return function () {
									return fn.apply(obj, args.concat(slice.call(arguments)));
								};
							};
						},
						{}
					],

					38: [
						function (_dereq_, module, exports) {
							/**
							 * Expose `Emitter`.
							 */

							module.exports = Emitter;

							/**
							 * Initialize a new `Emitter`.
							 *
							 * @api public
							 */

							function Emitter(obj) {
								if (obj) return mixin(obj);
							}

							/**
							 * Mixin the emitter properties.
							 *
							 * @param {Object} obj
							 * @return {Object}
							 * @api private
							 */

							function mixin(obj) {
								for (var key in Emitter.prototype) {
									obj[key] = Emitter.prototype[key];
								}
								return obj;
							}

							/**
							 * Listen on the given `event` with `fn`.
							 *
							 * @param {String} event
							 * @param {Function} fn
							 * @return {Emitter}
							 * @api public
							 */

							Emitter.prototype.on = Emitter.prototype.addEventListener = function (
								event,
								fn
							) {
								this._callbacks = this._callbacks || {};
								(this._callbacks["$" + event] =
									this._callbacks["$" + event] || []).push(fn);
								return this;
							};

							/**
							 * Adds an `event` listener that will be invoked a single
							 * time then automatically removed.
							 *
							 * @param {String} event
							 * @param {Function} fn
							 * @return {Emitter}
							 * @api public
							 */

							Emitter.prototype.once = function (event, fn) {
								function on() {
									this.off(event, on);
									fn.apply(this, arguments);
								}

								on.fn = fn;
								this.on(event, on);
								return this;
							};

							/**
							 * Remove the given callback for `event` or all
							 * registered callbacks.
							 *
							 * @param {String} event
							 * @param {Function} fn
							 * @return {Emitter}
							 * @api public
							 */

							Emitter.prototype.off =
								Emitter.prototype.removeListener =
								Emitter.prototype.removeAllListeners =
								Emitter.prototype.removeEventListener =
									function (event, fn) {
										this._callbacks = this._callbacks || {};

										// all
										if (0 == arguments.length) {
											this._callbacks = {};
											return this;
										}

										// specific event
										var callbacks = this._callbacks["$" + event];
										if (!callbacks) return this;

										// remove all handlers
										if (1 == arguments.length) {
											delete this._callbacks["$" + event];
											return this;
										}

										// remove specific handler
										var cb;
										for (var i = 0; i < callbacks.length; i++) {
											cb = callbacks[i];
											if (cb === fn || cb.fn === fn) {
												callbacks.splice(i, 1);
												break;
											}
										}
										return this;
									};

							/**
							 * Emit `event` with the given args.
							 *
							 * @param {String} event
							 * @param {Mixed} ...
							 * @return {Emitter}
							 */

							Emitter.prototype.emit = function (event) {
								this._callbacks = this._callbacks || {};
								var args = [].slice.call(arguments, 1),
									callbacks = this._callbacks["$" + event];

								if (callbacks) {
									callbacks = callbacks.slice(0);
									for (var i = 0, len = callbacks.length; i < len; ++i) {
										callbacks[i].apply(this, args);
									}
								}

								return this;
							};

							/**
							 * Return array of callbacks for `event`.
							 *
							 * @param {String} event
							 * @return {Array}
							 * @api public
							 */

							Emitter.prototype.listeners = function (event) {
								this._callbacks = this._callbacks || {};
								return this._callbacks["$" + event] || [];
							};

							/**
							 * Check if this emitter has `event` handlers.
							 *
							 * @param {String} event
							 * @return {Boolean}
							 * @api public
							 */

							Emitter.prototype.hasListeners = function (event) {
								return !!this.listeners(event).length;
							};
						},
						{}
					],

					39: [
						function (_dereq_, module, exports) {
							arguments[4][17][0].apply(exports, arguments);
						},
						{ "./debug": 40, dup: 17 }
					],

					40: [
						function (_dereq_, module, exports) {
							arguments[4][18][0].apply(exports, arguments);
						},
						{ dup: 18, ms: 44 }
					],

					41: [
						function (_dereq_, module, exports) {
							(function (global) {
								/*
								 * Module requirements.
								 */

								var isArray = _dereq_("isarray");

								/**
								 * Module exports.
								 */

								module.exports = hasBinary;

								/**
								 * Checks for binary data.
								 *
								 * Right now only Buffer and ArrayBuffer are supported..
								 *
								 * @param {Object} anything
								 * @api public
								 */

								function hasBinary(data) {
									function _hasBinary(obj) {
										if (!obj) return false;

										if (
											(global.Buffer &&
												global.Buffer.isBuffer &&
												global.Buffer.isBuffer(obj)) ||
											(global.ArrayBuffer && obj instanceof ArrayBuffer) ||
											(global.Blob && obj instanceof Blob) ||
											(global.File && obj instanceof File)
										) {
											return true;
										}

										if (isArray(obj)) {
											for (var i = 0; i < obj.length; i++) {
												if (_hasBinary(obj[i])) {
													return true;
												}
											}
										} else if (obj && "object" == typeof obj) {
											// see: https://github.com/Automattic/has-binary/pull/4
											if (obj.toJSON && "function" == typeof obj.toJSON) {
												obj = obj.toJSON();
											}

											for (var key in obj) {
												if (
													Object.prototype.hasOwnProperty.call(
														obj,
														key
													) &&
													_hasBinary(obj[key])
												) {
													return true;
												}
											}
										}

										return false;
									}

									return _hasBinary(data);
								}
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{ isarray: 43 }
					],

					42: [
						function (_dereq_, module, exports) {
							arguments[4][23][0].apply(exports, arguments);
						},
						{ dup: 23 }
					],

					43: [
						function (_dereq_, module, exports) {
							arguments[4][24][0].apply(exports, arguments);
						},
						{ dup: 24 }
					],

					44: [
						function (_dereq_, module, exports) {
							arguments[4][25][0].apply(exports, arguments);
						},
						{ dup: 25 }
					],

					45: [
						function (_dereq_, module, exports) {
							arguments[4][28][0].apply(exports, arguments);
						},
						{ dup: 28 }
					],

					46: [
						function (_dereq_, module, exports) {
							(function (global) {
								/*global Blob,File*/

								/**
								 * Module requirements
								 */

								var isArray = _dereq_("isarray");
								var isBuf = _dereq_("./is-buffer");

								/**
								 * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.
								 * Anything with blobs or files should be fed through removeBlobs before coming
								 * here.
								 *
								 * @param {Object} packet - socket.io event packet
								 * @return {Object} with deconstructed packet and list of buffers
								 * @api public
								 */

								exports.deconstructPacket = function (packet) {
									var buffers = [];
									var packetData = packet.data;

									function _deconstructPacket(data) {
										if (!data) return data;

										if (isBuf(data)) {
											var placeholder = {
												_placeholder: true,
												num: buffers.length
											};
											buffers.push(data);
											return placeholder;
										} else if (isArray(data)) {
											var newData = new Array(data.length);
											for (var i = 0; i < data.length; i++) {
												newData[i] = _deconstructPacket(data[i]);
											}
											return newData;
										} else if (
											"object" == typeof data &&
											!(data instanceof Date)
										) {
											var newData = {};
											for (var key in data) {
												newData[key] = _deconstructPacket(data[key]);
											}
											return newData;
										}
										return data;
									}

									var pack = packet;
									pack.data = _deconstructPacket(packetData);
									pack.attachments = buffers.length; // number of binary 'attachments'
									return { packet: pack, buffers: buffers };
								};

								/**
								 * Reconstructs a binary packet from its placeholder packet and buffers
								 *
								 * @param {Object} packet - event packet with placeholders
								 * @param {Array} buffers - binary buffers to put in placeholder positions
								 * @return {Object} reconstructed packet
								 * @api public
								 */

								exports.reconstructPacket = function (packet, buffers) {
									var curPlaceHolder = 0;

									function _reconstructPacket(data) {
										if (data && data._placeholder) {
											var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)
											return buf;
										} else if (isArray(data)) {
											for (var i = 0; i < data.length; i++) {
												data[i] = _reconstructPacket(data[i]);
											}
											return data;
										} else if (data && "object" == typeof data) {
											for (var key in data) {
												data[key] = _reconstructPacket(data[key]);
											}
											return data;
										}
										return data;
									}

									packet.data = _reconstructPacket(packet.data);
									packet.attachments = undefined; // no longer useful
									return packet;
								};

								/**
								 * Asynchronously removes Blobs or Files from data via
								 * FileReader's readAsArrayBuffer method. Used before encoding
								 * data as msgpack. Calls callback with the blobless data.
								 *
								 * @param {Object} data
								 * @param {Function} callback
								 * @api private
								 */

								exports.removeBlobs = function (data, callback) {
									function _removeBlobs(obj, curKey, containingObject) {
										if (!obj) return obj;

										// convert any blob
										if (
											(global.Blob && obj instanceof Blob) ||
											(global.File && obj instanceof File)
										) {
											pendingBlobs++;

											// async filereader
											var fileReader = new FileReader();
											fileReader.onload = function () {
												// this.result == arraybuffer
												if (containingObject) {
													containingObject[curKey] = this.result;
												} else {
													bloblessData = this.result;
												}

												// if nothing pending its callback time
												if (!--pendingBlobs) {
													callback(bloblessData);
												}
											};

											fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer
										} else if (isArray(obj)) {
											// handle array
											for (var i = 0; i < obj.length; i++) {
												_removeBlobs(obj[i], i, obj);
											}
										} else if (obj && "object" == typeof obj && !isBuf(obj)) {
											// and object
											for (var key in obj) {
												_removeBlobs(obj[key], key, obj);
											}
										}
									}

									var pendingBlobs = 0;
									var bloblessData = data;
									_removeBlobs(bloblessData);
									if (!pendingBlobs) {
										callback(bloblessData);
									}
								};
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{ "./is-buffer": 48, isarray: 43 }
					],

					47: [
						function (_dereq_, module, exports) {
							/**
							 * Module dependencies.
							 */

							var debug = _dereq_("debug")("socket.io-parser");
							var json = _dereq_("json3");
							var isArray = _dereq_("isarray");
							var Emitter = _dereq_("component-emitter");
							var binary = _dereq_("./binary");
							var isBuf = _dereq_("./is-buffer");

							/**
							 * Protocol version.
							 *
							 * @api public
							 */

							exports.protocol = 4;

							/**
							 * Packet types.
							 *
							 * @api public
							 */

							exports.types = [
								"CONNECT",
								"DISCONNECT",
								"EVENT",
								"BINARY_EVENT",
								"ACK",
								"BINARY_ACK",
								"ERROR"
							];

							/**
							 * Packet type `connect`.
							 *
							 * @api public
							 */

							exports.CONNECT = 0;

							/**
							 * Packet type `disconnect`.
							 *
							 * @api public
							 */

							exports.DISCONNECT = 1;

							/**
							 * Packet type `event`.
							 *
							 * @api public
							 */

							exports.EVENT = 2;

							/**
							 * Packet type `ack`.
							 *
							 * @api public
							 */

							exports.ACK = 3;

							/**
							 * Packet type `error`.
							 *
							 * @api public
							 */

							exports.ERROR = 4;

							/**
							 * Packet type 'binary event'
							 *
							 * @api public
							 */

							exports.BINARY_EVENT = 5;

							/**
							 * Packet type `binary ack`. For acks with binary arguments.
							 *
							 * @api public
							 */

							exports.BINARY_ACK = 6;

							/**
							 * Encoder constructor.
							 *
							 * @api public
							 */

							exports.Encoder = Encoder;

							/**
							 * Decoder constructor.
							 *
							 * @api public
							 */

							exports.Decoder = Decoder;

							/**
							 * A socket.io Encoder instance
							 *
							 * @api public
							 */

							function Encoder() {}

							/**
							 * Encode a packet as a single string if non-binary, or as a
							 * buffer sequence, depending on packet type.
							 *
							 * @param {Object} obj - packet object
							 * @param {Function} callback - function to handle encodings (likely engine.write)
							 * @return Calls callback with Array of encodings
							 * @api public
							 */

							Encoder.prototype.encode = function (obj, callback) {
								debug("encoding packet %j", obj);

								if (
									exports.BINARY_EVENT == obj.type ||
									exports.BINARY_ACK == obj.type
								) {
									encodeAsBinary(obj, callback);
								} else {
									var encoding = encodeAsString(obj);
									callback([encoding]);
								}
							};

							/**
							 * Encode packet as string.
							 *
							 * @param {Object} packet
							 * @return {String} encoded
							 * @api private
							 */

							function encodeAsString(obj) {
								var str = "";
								var nsp = false;

								// first is type
								str += obj.type;

								// attachments if we have them
								if (
									exports.BINARY_EVENT == obj.type ||
									exports.BINARY_ACK == obj.type
								) {
									str += obj.attachments;
									str += "-";
								}

								// if we have a namespace other than `/`
								// we append it followed by a comma `,`
								if (obj.nsp && "/" != obj.nsp) {
									nsp = true;
									str += obj.nsp;
								}

								// immediately followed by the id
								if (null != obj.id) {
									if (nsp) {
										str += ",";
										nsp = false;
									}
									str += obj.id;
								}

								// json data
								if (null != obj.data) {
									if (nsp) str += ",";
									str += json.stringify(obj.data);
								}

								debug("encoded %j as %s", obj, str);
								return str;
							}

							/**
							 * Encode packet as 'buffer sequence' by removing blobs, and
							 * deconstructing packet into object with placeholders and
							 * a list of buffers.
							 *
							 * @param {Object} packet
							 * @return {Buffer} encoded
							 * @api private
							 */

							function encodeAsBinary(obj, callback) {
								function writeEncoding(bloblessData) {
									var deconstruction = binary.deconstructPacket(bloblessData);
									var pack = encodeAsString(deconstruction.packet);
									var buffers = deconstruction.buffers;

									buffers.unshift(pack); // add packet info to beginning of data list
									callback(buffers); // write all the buffers
								}

								binary.removeBlobs(obj, writeEncoding);
							}

							/**
							 * A socket.io Decoder instance
							 *
							 * @return {Object} decoder
							 * @api public
							 */

							function Decoder() {
								this.reconstructor = null;
							}

							/**
							 * Mix in `Emitter` with Decoder.
							 */

							Emitter(Decoder.prototype);

							/**
							 * Decodes an ecoded packet string into packet JSON.
							 *
							 * @param {String} obj - encoded packet
							 * @return {Object} packet
							 * @api public
							 */

							Decoder.prototype.add = function (obj) {
								var packet;
								if ("string" == typeof obj) {
									packet = decodeString(obj);
									if (
										exports.BINARY_EVENT == packet.type ||
										exports.BINARY_ACK == packet.type
									) {
										// binary packet's json
										this.reconstructor = new BinaryReconstructor(packet);

										// no attachments, labeled binary but no binary data to follow
										if (this.reconstructor.reconPack.attachments === 0) {
											this.emit("decoded", packet);
										}
									} else {
										// non-binary full packet
										this.emit("decoded", packet);
									}
								} else if (isBuf(obj) || obj.base64) {
									// raw binary data
									if (!this.reconstructor) {
										throw new Error(
											"got binary data when not reconstructing a packet"
										);
									} else {
										packet = this.reconstructor.takeBinaryData(obj);
										if (packet) {
											// received final buffer
											this.reconstructor = null;
											this.emit("decoded", packet);
										}
									}
								} else {
									throw new Error("Unknown type: " + obj);
								}
							};

							/**
							 * Decode a packet String (JSON data)
							 *
							 * @param {String} str
							 * @return {Object} packet
							 * @api private
							 */

							function decodeString(str) {
								var p = {};
								var i = 0;

								// look up type
								p.type = Number(str.charAt(0));
								if (null == exports.types[p.type]) return error();

								// look up attachments if type binary
								if (
									exports.BINARY_EVENT == p.type ||
									exports.BINARY_ACK == p.type
								) {
									var buf = "";
									while (str.charAt(++i) != "-") {
										buf += str.charAt(i);
										if (i == str.length) break;
									}
									if (buf != Number(buf) || str.charAt(i) != "-") {
										throw new Error("Illegal attachments");
									}
									p.attachments = Number(buf);
								}

								// look up namespace (if any)
								if ("/" == str.charAt(i + 1)) {
									p.nsp = "";
									while (++i) {
										var c = str.charAt(i);
										if ("," == c) break;
										p.nsp += c;
										if (i == str.length) break;
									}
								} else {
									p.nsp = "/";
								}

								// look up id
								var next = str.charAt(i + 1);
								if ("" !== next && Number(next) == next) {
									p.id = "";
									while (++i) {
										var c = str.charAt(i);
										if (null == c || Number(c) != c) {
											--i;
											break;
										}
										p.id += str.charAt(i);
										if (i == str.length) break;
									}
									p.id = Number(p.id);
								}

								// look up json data
								if (str.charAt(++i)) {
									try {
										p.data = json.parse(str.substr(i));
									} catch (e) {
										return error();
									}
								}

								debug("decoded %s as %j", str, p);
								return p;
							}

							/**
							 * Deallocates a parser's resources
							 *
							 * @api public
							 */

							Decoder.prototype.destroy = function () {
								if (this.reconstructor) {
									this.reconstructor.finishedReconstruction();
								}
							};

							/**
							 * A manager of a binary event's 'buffer sequence'. Should
							 * be constructed whenever a packet of type BINARY_EVENT is
							 * decoded.
							 *
							 * @param {Object} packet
							 * @return {BinaryReconstructor} initialized reconstructor
							 * @api private
							 */

							function BinaryReconstructor(packet) {
								this.reconPack = packet;
								this.buffers = [];
							}

							/**
							 * Method to be called when binary data received from connection
							 * after a BINARY_EVENT packet.
							 *
							 * @param {Buffer | ArrayBuffer} binData - the raw binary data received
							 * @return {null | Object} returns null if more binary data is expected or
							 *   a reconstructed packet object if all buffers have been received.
							 * @api private
							 */

							BinaryReconstructor.prototype.takeBinaryData = function (binData) {
								this.buffers.push(binData);
								if (this.buffers.length == this.reconPack.attachments) {
									// done with buffer list
									var packet = binary.reconstructPacket(
										this.reconPack,
										this.buffers
									);
									this.finishedReconstruction();
									return packet;
								}
								return null;
							};

							/**
							 * Cleans up binary packet reconstruction variables.
							 *
							 * @api private
							 */

							BinaryReconstructor.prototype.finishedReconstruction = function () {
								this.reconPack = null;
								this.buffers = [];
							};

							function error(data) {
								return {
									type: exports.ERROR,
									data: "parser error"
								};
							}
						},
						{
							"./binary": 46,
							"./is-buffer": 48,
							"component-emitter": 49,
							debug: 39,
							isarray: 43,
							json3: 50
						}
					],

					48: [
						function (_dereq_, module, exports) {
							(function (global) {
								module.exports = isBuf;

								/**
								 * Returns true if obj is a buffer or an arraybuffer.
								 *
								 * @api private
								 */

								function isBuf(obj) {
									return (
										(global.Buffer && global.Buffer.isBuffer(obj)) ||
										(global.ArrayBuffer && obj instanceof ArrayBuffer)
									);
								}
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{}
					],

					49: [
						function (_dereq_, module, exports) {
							arguments[4][15][0].apply(exports, arguments);
						},
						{ dup: 15 }
					],

					50: [
						function (_dereq_, module, exports) {
							(function (global) {
								/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */
								(function () {
									// Detect the `define` function exposed by asynchronous module loaders. The
									// strict `define` check is necessary for compatibility with `r.js`.
									var isLoader = typeof define === "function" && define.amd;

									// A set of types used to distinguish objects from primitives.
									var objectTypes = {
										function: true,
										object: true
									};

									// Detect the `exports` object exposed by CommonJS implementations.
									var freeExports =
										objectTypes[typeof exports] &&
										exports &&
										!exports.nodeType &&
										exports;

									// Use the `global` object exposed by Node (including Browserify via
									// `insert-module-globals`), Narwhal, and Ringo as the default context,
									// and the `window` object in browsers. Rhino exports a `global` function
									// instead.
									var root = (objectTypes[typeof window] && window) || this,
										freeGlobal =
											freeExports &&
											objectTypes[typeof module] &&
											module &&
											!module.nodeType &&
											typeof global == "object" &&
											global;

									if (
										freeGlobal &&
										(freeGlobal["global"] === freeGlobal ||
											freeGlobal["window"] === freeGlobal ||
											freeGlobal["self"] === freeGlobal)
									) {
										root = freeGlobal;
									}

									// Public: Initializes JSON 3 using the given `context` object, attaching the
									// `stringify` and `parse` functions to the specified `exports` object.
									function runInContext(context, exports) {
										context || (context = root["Object"]());
										exports || (exports = root["Object"]());

										// Native constructor aliases.
										var Number = context["Number"] || root["Number"],
											String = context["String"] || root["String"],
											Object = context["Object"] || root["Object"],
											Date = context["Date"] || root["Date"],
											SyntaxError =
												context["SyntaxError"] || root["SyntaxError"],
											TypeError = context["TypeError"] || root["TypeError"],
											Math = context["Math"] || root["Math"],
											nativeJSON = context["JSON"] || root["JSON"];

										// Delegate to the native `stringify` and `parse` implementations.
										if (typeof nativeJSON == "object" && nativeJSON) {
											exports.stringify = nativeJSON.stringify;
											exports.parse = nativeJSON.parse;
										}

										// Convenience aliases.
										var objectProto = Object.prototype,
											getClass = objectProto.toString,
											isProperty,
											forEach,
											undef;

										// Test the `Date#getUTC*` methods. Based on work by @Yaffle.
										var isExtended = new Date(-3509827334573292);
										try {
											// The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical
											// results for certain dates in Opera >= 10.53.
											isExtended =
												isExtended.getUTCFullYear() == -109252 &&
												isExtended.getUTCMonth() === 0 &&
												isExtended.getUTCDate() === 1 &&
												// Safari < 2.0.2 stores the internal millisecond time value correctly,
												// but clips the values returned by the date methods to the range of
												// signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).
												isExtended.getUTCHours() == 10 &&
												isExtended.getUTCMinutes() == 37 &&
												isExtended.getUTCSeconds() == 6 &&
												isExtended.getUTCMilliseconds() == 708;
										} catch (exception) {}

										// Internal: Determines whether the native `JSON.stringify` and `parse`
										// implementations are spec-compliant. Based on work by Ken Snyder.
										function has(name) {
											if (has[name] !== undef) {
												// Return cached feature test result.
												return has[name];
											}
											var isSupported;
											if (name == "bug-string-char-index") {
												// IE <= 7 doesn't support accessing string characters using square
												// bracket notation. IE 8 only supports this for primitives.
												isSupported = "a"[0] != "a";
											} else if (name == "json") {
												// Indicates whether both `JSON.stringify` and `JSON.parse` are
												// supported.
												isSupported =
													has("json-stringify") && has("json-parse");
											} else {
												var value,
													serialized =
														'{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
												// Test `JSON.stringify`.
												if (name == "json-stringify") {
													var stringify = exports.stringify,
														stringifySupported =
															typeof stringify == "function" &&
															isExtended;
													if (stringifySupported) {
														// A test function object with a custom `toJSON` method.
														(value = function () {
															return 1;
														}).toJSON = value;
														try {
															stringifySupported =
																// Firefox 3.1b1 and b2 serialize string, number, and boolean
																// primitives as object literals.
																stringify(0) === "0" &&
																// FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
																// literals.
																stringify(new Number()) === "0" &&
																stringify(new String()) == '""' &&
																// FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
																// does not define a canonical JSON representation (this applies to
																// objects with `toJSON` properties as well, *unless* they are nested
																// within an object or array).
																stringify(getClass) === undef &&
																// IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
																// FF 3.1b3 pass this test.
																stringify(undef) === undef &&
																// Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
																// respectively, if the value is omitted entirely.
																stringify() === undef &&
																// FF 3.1b1, 2 throw an error if the given value is not a number,
																// string, array, object, Boolean, or `null` literal. This applies to
																// objects with custom `toJSON` methods as well, unless they are nested
																// inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
																// methods entirely.
																stringify(value) === "1" &&
																stringify([value]) == "[1]" &&
																// Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
																// `"[null]"`.
																stringify([undef]) == "[null]" &&
																// YUI 3.0.0b1 fails to serialize `null` literals.
																stringify(null) == "null" &&
																// FF 3.1b1, 2 halts serialization if an array contains a function:
																// `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3
																// elides non-JSON values from objects and arrays, unless they
																// define custom `toJSON` methods.
																stringify([
																	undef,
																	getClass,
																	null
																]) == "[null,null,null]" &&
																// Simple serialization test. FF 3.1b1 uses Unicode escape sequences
																// where character escape codes are expected (e.g., `\b` => `\u0008`).
																stringify({
																	a: [
																		value,
																		true,
																		false,
																		null,
																		"\x00\b\n\f\r\t"
																	]
																}) == serialized &&
																// FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
																stringify(null, value) === "1" &&
																stringify([1, 2], null, 1) ==
																	"[\n 1,\n 2\n]" &&
																// JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
																// serialize extended years.
																stringify(new Date(-8.64e15)) ==
																	'"-271821-04-20T00:00:00.000Z"' &&
																// The milliseconds are optional in ES 5, but required in 5.1.
																stringify(new Date(8.64e15)) ==
																	'"+275760-09-13T00:00:00.000Z"' &&
																// Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
																// four-digit years instead of six-digit years. Credits: @Yaffle.
																stringify(new Date(-621987552e5)) ==
																	'"-000001-01-01T00:00:00.000Z"' &&
																// Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
																// values less than 1000. Credits: @Yaffle.
																stringify(new Date(-1)) ==
																	'"1969-12-31T23:59:59.999Z"';
														} catch (exception) {
															stringifySupported = false;
														}
													}
													isSupported = stringifySupported;
												}
												// Test `JSON.parse`.
												if (name == "json-parse") {
													var parse = exports.parse;
													if (typeof parse == "function") {
														try {
															// FF 3.1b1, b2 will throw an exception if a bare literal is provided.
															// Conforming implementations should also coerce the initial argument to
															// a string prior to parsing.
															if (parse("0") === 0 && !parse(false)) {
																// Simple parsing test.
																value = parse(serialized);
																var parseSupported =
																	value["a"].length == 5 &&
																	value["a"][0] === 1;
																if (parseSupported) {
																	try {
																		// Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
																		parseSupported =
																			!parse('"\t"');
																	} catch (exception) {}
																	if (parseSupported) {
																		try {
																			// FF 4.0 and 4.0.1 allow leading `+` signs and leading
																			// decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow
																			// certain octal literals.
																			parseSupported =
																				parse("01") !== 1;
																		} catch (exception) {}
																	}
																	if (parseSupported) {
																		try {
																			// FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal
																			// points. These environments, along with FF 3.1b1 and 2,
																			// also allow trailing commas in JSON objects and arrays.
																			parseSupported =
																				parse("1.") !== 1;
																		} catch (exception) {}
																	}
																}
															}
														} catch (exception) {
															parseSupported = false;
														}
													}
													isSupported = parseSupported;
												}
											}
											return (has[name] = !!isSupported);
										}

										if (!has("json")) {
											// Common `[[Class]]` name aliases.
											var functionClass = "[object Function]",
												dateClass = "[object Date]",
												numberClass = "[object Number]",
												stringClass = "[object String]",
												arrayClass = "[object Array]",
												booleanClass = "[object Boolean]";

											// Detect incomplete support for accessing string characters by index.
											var charIndexBuggy = has("bug-string-char-index");

											// Define additional utility methods if the `Date` methods are buggy.
											if (!isExtended) {
												var floor = Math.floor;
												// A mapping between the months of the year and the number of days between
												// January 1st and the first of the respective month.
												var Months = [
													0, 31, 59, 90, 120, 151, 181, 212, 243, 273,
													304, 334
												];

												// Internal: Calculates the number of days between the Unix epoch and the
												// first day of the given month.
												var getDay = function (year, month) {
													return (
														Months[month] +
														365 * (year - 1970) +
														floor(
															(year - 1969 + (month = +(month > 1))) /
																4
														) -
														floor((year - 1901 + month) / 100) +
														floor((year - 1601 + month) / 400)
													);
												};
											}

											// Internal: Determines if a property is a direct property of the given
											// object. Delegates to the native `Object#hasOwnProperty` method.
											if (!(isProperty = objectProto.hasOwnProperty)) {
												isProperty = function (property) {
													var members = {},
														constructor;
													if (
														((members.__proto__ = null),
														(members.__proto__ = {
															// The *proto* property cannot be set multiple times in recent
															// versions of Firefox and SeaMonkey.
															toString: 1
														}),
														members).toString != getClass
													) {
														// Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but
														// supports the mutable *proto* property.
														isProperty = function (property) {
															// Capture and break the object's prototype chain (see section 8.6.2
															// of the ES 5.1 spec). The parenthesized expression prevents an
															// unsafe transformation by the Closure Compiler.
															var original = this.__proto__,
																result =
																	property in
																	((this.__proto__ = null), this);
															// Restore the original prototype chain.
															this.__proto__ = original;
															return result;
														};
													} else {
														// Capture a reference to the top-level `Object` constructor.
														constructor = members.constructor;
														// Use the `constructor` property to simulate `Object#hasOwnProperty` in
														// other environments.
														isProperty = function (property) {
															var parent = (
																this.constructor || constructor
															).prototype;
															return (
																property in this &&
																!(
																	property in parent &&
																	this[property] ===
																		parent[property]
																)
															);
														};
													}
													members = null;
													return isProperty.call(this, property);
												};
											}

											// Internal: Normalizes the `for...in` iteration algorithm across
											// environments. Each enumerated key is yielded to a `callback` function.
											forEach = function (object, callback) {
												var size = 0,
													Properties,
													members,
													property;

												// Tests for bugs in the current environment's `for...in` algorithm. The
												// `valueOf` property inherits the non-enumerable flag from
												// `Object.prototype` in older versions of IE, Netscape, and Mozilla.
												(Properties = function () {
													this.valueOf = 0;
												}).prototype.valueOf = 0;

												// Iterate over a new instance of the `Properties` class.
												members = new Properties();
												for (property in members) {
													// Ignore all properties inherited from `Object.prototype`.
													if (isProperty.call(members, property)) {
														size++;
													}
												}
												Properties = members = null;

												// Normalize the iteration algorithm.
												if (!size) {
													// A list of non-enumerable properties inherited from `Object.prototype`.
													members = [
														"valueOf",
														"toString",
														"toLocaleString",
														"propertyIsEnumerable",
														"isPrototypeOf",
														"hasOwnProperty",
														"constructor"
													];

													// IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable
													// properties.
													forEach = function (object, callback) {
														var isFunction =
																getClass.call(object) ==
																functionClass,
															property,
															length;
														var hasProperty =
															(!isFunction &&
																typeof object.constructor !=
																	"function" &&
																objectTypes[
																	typeof object.hasOwnProperty
																] &&
																object.hasOwnProperty) ||
															isProperty;
														for (property in object) {
															// Gecko <= 1.0 enumerates the `prototype` property of functions under
															// certain conditions; IE does not.
															if (
																!(
																	isFunction &&
																	property == "prototype"
																) &&
																hasProperty.call(object, property)
															) {
																callback(property);
															}
														}
														// Manually invoke the callback for each non-enumerable property.
														for (
															length = members.length;
															(property = members[--length]);
															hasProperty.call(object, property) &&
															callback(property)
														);
													};
												} else if (size == 2) {
													// Safari <= 2.0.4 enumerates shadowed properties twice.
													forEach = function (object, callback) {
														// Create a set of iterated properties.
														var members = {},
															isFunction =
																getClass.call(object) ==
																functionClass,
															property;
														for (property in object) {
															// Store each property name to prevent double enumeration. The
															// `prototype` property of functions is not enumerated due to cross-
															// environment inconsistencies.
															if (
																!(
																	isFunction &&
																	property == "prototype"
																) &&
																!isProperty.call(
																	members,
																	property
																) &&
																(members[property] = 1) &&
																isProperty.call(object, property)
															) {
																callback(property);
															}
														}
													};
												} else {
													// No bugs detected; use the standard `for...in` algorithm.
													forEach = function (object, callback) {
														var isFunction =
																getClass.call(object) ==
																functionClass,
															property,
															isConstructor;
														for (property in object) {
															if (
																!(
																	isFunction &&
																	property == "prototype"
																) &&
																isProperty.call(object, property) &&
																!(isConstructor =
																	property === "constructor")
															) {
																callback(property);
															}
														}
														// Manually invoke the callback for the `constructor` property due to
														// cross-environment inconsistencies.
														if (
															isConstructor ||
															isProperty.call(
																object,
																(property = "constructor")
															)
														) {
															callback(property);
														}
													};
												}
												return forEach(object, callback);
											};

											// Public: Serializes a JavaScript `value` as a JSON string. The optional
											// `filter` argument may specify either a function that alters how object and
											// array members are serialized, or an array of strings and numbers that
											// indicates which properties should be serialized. The optional `width`
											// argument may be either a string or number that specifies the indentation
											// level of the output.
											if (!has("json-stringify")) {
												// Internal: A map of control characters and their escaped equivalents.
												var Escapes = {
													92: "\\\\",
													34: '\\"',
													8: "\\b",
													12: "\\f",
													10: "\\n",
													13: "\\r",
													9: "\\t"
												};

												// Internal: Converts `value` into a zero-padded string such that its
												// length is at least equal to `width`. The `width` must be <= 6.
												var leadingZeroes = "000000";
												var toPaddedString = function (width, value) {
													// The `|| 0` expression is necessary to work around a bug in
													// Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`.
													return (leadingZeroes + (value || 0)).slice(
														-width
													);
												};

												// Internal: Double-quotes a string `value`, replacing all ASCII control
												// characters (characters with code unit values between 0 and 31) with
												// their escaped equivalents. This is an implementation of the
												// `Quote(value)` operation defined in ES 5.1 section 15.12.3.
												var unicodePrefix = "\\u00";
												var quote = function (value) {
													var result = '"',
														index = 0,
														length = value.length,
														useCharIndex =
															!charIndexBuggy || length > 10;
													var symbols =
														useCharIndex &&
														(charIndexBuggy ? value.split("") : value);
													for (; index < length; index++) {
														var charCode = value.charCodeAt(index);
														// If the character is a control character, append its Unicode or
														// shorthand escape sequence; otherwise, append the character as-is.
														switch (charCode) {
															case 8:
															case 9:
															case 10:
															case 12:
															case 13:
															case 34:
															case 92:
																result += Escapes[charCode];
																break;
															default:
																if (charCode < 32) {
																	result +=
																		unicodePrefix +
																		toPaddedString(
																			2,
																			charCode.toString(16)
																		);
																	break;
																}
																result += useCharIndex
																	? symbols[index]
																	: value.charAt(index);
														}
													}
													return result + '"';
												};

												// Internal: Recursively serializes an object. Implements the
												// `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.
												var serialize = function (
													property,
													object,
													callback,
													properties,
													whitespace,
													indentation,
													stack
												) {
													var value,
														className,
														year,
														month,
														date,
														time,
														hours,
														minutes,
														seconds,
														milliseconds,
														results,
														element,
														index,
														length,
														prefix,
														result;
													try {
														// Necessary for host object support.
														value = object[property];
													} catch (exception) {}
													if (typeof value == "object" && value) {
														className = getClass.call(value);
														if (
															className == dateClass &&
															!isProperty.call(value, "toJSON")
														) {
															if (value > -1 / 0 && value < 1 / 0) {
																// Dates are serialized according to the `Date#toJSON` method
																// specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15
																// for the ISO 8601 date time string format.
																if (getDay) {
																	// Manually compute the year, month, date, hours, minutes,
																	// seconds, and milliseconds if the `getUTC*` methods are
																	// buggy. Adapted from @Yaffle's `date-shim` project.
																	date = floor(value / 864e5);
																	for (
																		year =
																			floor(date / 365.2425) +
																			1970 -
																			1;
																		getDay(year + 1, 0) <= date;
																		year++
																	);
																	for (
																		month = floor(
																			(date -
																				getDay(year, 0)) /
																				30.42
																		);
																		getDay(year, month + 1) <=
																		date;
																		month++
																	);
																	date =
																		1 +
																		date -
																		getDay(year, month);
																	// The `time` value specifies the time within the day (see ES
																	// 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used
																	// to compute `A modulo B`, as the `%` operator does not
																	// correspond to the `modulo` operation for negative numbers.
																	time =
																		((value % 864e5) + 864e5) %
																		864e5;
																	// The hours, minutes, seconds, and milliseconds are obtained by
																	// decomposing the time within the day. See section 15.9.1.10.
																	hours = floor(time / 36e5) % 24;
																	minutes =
																		floor(time / 6e4) % 60;
																	seconds =
																		floor(time / 1e3) % 60;
																	milliseconds = time % 1e3;
																} else {
																	year = value.getUTCFullYear();
																	month = value.getUTCMonth();
																	date = value.getUTCDate();
																	hours = value.getUTCHours();
																	minutes = value.getUTCMinutes();
																	seconds = value.getUTCSeconds();
																	milliseconds =
																		value.getUTCMilliseconds();
																}
																// Serialize extended years correctly.
																value =
																	(year <= 0 || year >= 1e4
																		? (year < 0 ? "-" : "+") +
																			toPaddedString(
																				6,
																				year < 0
																					? -year
																					: year
																			)
																		: toPaddedString(4, year)) +
																	"-" +
																	toPaddedString(2, month + 1) +
																	"-" +
																	toPaddedString(2, date) +
																	// Months, dates, hours, minutes, and seconds should have two
																	// digits; milliseconds should have three.
																	"T" +
																	toPaddedString(2, hours) +
																	":" +
																	toPaddedString(2, minutes) +
																	":" +
																	toPaddedString(2, seconds) +
																	// Milliseconds are optional in ES 5.0, but required in 5.1.
																	"." +
																	toPaddedString(
																		3,
																		milliseconds
																	) +
																	"Z";
															} else {
																value = null;
															}
														} else if (
															typeof value.toJSON == "function" &&
															((className != numberClass &&
																className != stringClass &&
																className != arrayClass) ||
																isProperty.call(value, "toJSON"))
														) {
															// Prototype <= 1.6.1 adds non-standard `toJSON` methods to the
															// `Number`, `String`, `Date`, and `Array` prototypes. JSON 3
															// ignores all `toJSON` methods on these objects unless they are
															// defined directly on an instance.
															value = value.toJSON(property);
														}
													}
													if (callback) {
														// If a replacement function was provided, call it to obtain the value
														// for serialization.
														value = callback.call(
															object,
															property,
															value
														);
													}
													if (value === null) {
														return "null";
													}
													className = getClass.call(value);
													if (className == booleanClass) {
														// Booleans are represented literally.
														return "" + value;
													} else if (className == numberClass) {
														// JSON numbers must be finite. `Infinity` and `NaN` are serialized as
														// `"null"`.
														return value > -1 / 0 && value < 1 / 0
															? "" + value
															: "null";
													} else if (className == stringClass) {
														// Strings are double-quoted and escaped.
														return quote("" + value);
													}
													// Recursively serialize objects and arrays.
													if (typeof value == "object") {
														// Check for cyclic structures. This is a linear search; performance
														// is inversely proportional to the number of unique nested objects.
														for (length = stack.length; length--; ) {
															if (stack[length] === value) {
																// Cyclic structures cannot be serialized by `JSON.stringify`.
																throw TypeError();
															}
														}
														// Add the object to the stack of traversed objects.
														stack.push(value);
														results = [];
														// Save the current indentation level and indent one additional level.
														prefix = indentation;
														indentation += whitespace;
														if (className == arrayClass) {
															// Recursively serialize array elements.
															for (
																index = 0, length = value.length;
																index < length;
																index++
															) {
																element = serialize(
																	index,
																	value,
																	callback,
																	properties,
																	whitespace,
																	indentation,
																	stack
																);
																results.push(
																	element === undef
																		? "null"
																		: element
																);
															}
															result = results.length
																? whitespace
																	? "[\n" +
																		indentation +
																		results.join(
																			",\n" + indentation
																		) +
																		"\n" +
																		prefix +
																		"]"
																	: "[" + results.join(",") + "]"
																: "[]";
														} else {
															// Recursively serialize object members. Members are selected from
															// either a user-specified list of property names, or the object
															// itself.
															forEach(
																properties || value,
																function (property) {
																	var element = serialize(
																		property,
																		value,
																		callback,
																		properties,
																		whitespace,
																		indentation,
																		stack
																	);
																	if (element !== undef) {
																		// According to ES 5.1 section 15.12.3: "If `gap` {whitespace}
																		// is not the empty string, let `member` {quote(property) + ":"}
																		// be the concatenation of `member` and the `space` character."
																		// The "`space` character" refers to the literal space
																		// character, not the `space` {width} argument provided to
																		// `JSON.stringify`.
																		results.push(
																			quote(property) +
																				":" +
																				(whitespace
																					? " "
																					: "") +
																				element
																		);
																	}
																}
															);
															result = results.length
																? whitespace
																	? "{\n" +
																		indentation +
																		results.join(
																			",\n" + indentation
																		) +
																		"\n" +
																		prefix +
																		"}"
																	: "{" + results.join(",") + "}"
																: "{}";
														}
														// Remove the object from the traversed object stack.
														stack.pop();
														return result;
													}
												};

												// Public: `JSON.stringify`. See ES 5.1 section 15.12.3.
												exports.stringify = function (
													source,
													filter,
													width
												) {
													var whitespace, callback, properties, className;
													if (objectTypes[typeof filter] && filter) {
														if (
															(className = getClass.call(filter)) ==
															functionClass
														) {
															callback = filter;
														} else if (className == arrayClass) {
															// Convert the property names array into a makeshift set.
															properties = {};
															for (
																var index = 0,
																	length = filter.length,
																	value;
																index < length;
																value = filter[index++],
																	((className =
																		getClass.call(value)),
																	className == stringClass ||
																		className == numberClass) &&
																		(properties[value] = 1)
															);
														}
													}
													if (width) {
														if (
															(className = getClass.call(width)) ==
															numberClass
														) {
															// Convert the `width` to an integer and create a string containing
															// `width` number of space characters.
															if ((width -= width % 1) > 0) {
																for (
																	whitespace = "",
																		width > 10 && (width = 10);
																	whitespace.length < width;
																	whitespace += " "
																);
															}
														} else if (className == stringClass) {
															whitespace =
																width.length <= 10
																	? width
																	: width.slice(0, 10);
														}
													}
													// Opera <= 7.54u2 discards the values associated with empty string keys
													// (`""`) only if they are used directly within an object member list
													// (e.g., `!("" in { "": 1})`).
													return serialize(
														"",
														((value = {}), (value[""] = source), value),
														callback,
														properties,
														whitespace,
														"",
														[]
													);
												};
											}

											// Public: Parses a JSON source string.
											if (!has("json-parse")) {
												var fromCharCode = String.fromCharCode;

												// Internal: A map of escaped control characters and their unescaped
												// equivalents.
												var Unescapes = {
													92: "\\",
													34: '"',
													47: "/",
													98: "\b",
													116: "\t",
													110: "\n",
													102: "\f",
													114: "\r"
												};

												// Internal: Stores the parser state.
												var Index, Source;

												// Internal: Resets the parser state and throws a `SyntaxError`.
												var abort = function () {
													Index = Source = null;
													throw SyntaxError();
												};

												// Internal: Returns the next token, or `"$"` if the parser has reached
												// the end of the source string. A token may be a string, number, `null`
												// literal, or Boolean literal.
												var lex = function () {
													var source = Source,
														length = source.length,
														value,
														begin,
														position,
														isSigned,
														charCode;
													while (Index < length) {
														charCode = source.charCodeAt(Index);
														switch (charCode) {
															case 9:
															case 10:
															case 13:
															case 32:
																// Skip whitespace tokens, including tabs, carriage returns, line
																// feeds, and space characters.
																Index++;
																break;
															case 123:
															case 125:
															case 91:
															case 93:
															case 58:
															case 44:
																// Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at
																// the current position.
																value = charIndexBuggy
																	? source.charAt(Index)
																	: source[Index];
																Index++;
																return value;
															case 34:
																// `"` delimits a JSON string; advance to the next character and
																// begin parsing the string. String tokens are prefixed with the
																// sentinel `@` character to distinguish them from punctuators and
																// end-of-string tokens.
																for (
																	value = "@", Index++;
																	Index < length;

																) {
																	charCode =
																		source.charCodeAt(Index);
																	if (charCode < 32) {
																		// Unescaped ASCII control characters (those with a code unit
																		// less than the space character) are not permitted.
																		abort();
																	} else if (charCode == 92) {
																		// A reverse solidus (`\`) marks the beginning of an escaped
																		// control character (including `"`, `\`, and `/`) or Unicode
																		// escape sequence.
																		charCode =
																			source.charCodeAt(
																				++Index
																			);
																		switch (charCode) {
																			case 92:
																			case 34:
																			case 47:
																			case 98:
																			case 116:
																			case 110:
																			case 102:
																			case 114:
																				// Revive escaped control characters.
																				value +=
																					Unescapes[
																						charCode
																					];

																				Index++;
																				break;
																			case 117:
																				// `\u` marks the beginning of a Unicode escape sequence.
																				// Advance to the first character and validate the
																				// four-digit code point.
																				begin = ++Index;
																				for (
																					position =
																						Index + 4;
																					Index <
																					position;
																					Index++
																				) {
																					charCode =
																						source.charCodeAt(
																							Index
																						);
																					// A valid sequence comprises four hexdigits (case-
																					// insensitive) that form a single hexadecimal value.
																					if (
																						!(
																							(charCode >=
																								48 &&
																								charCode <=
																									57) ||
																							(charCode >=
																								97 &&
																								charCode <=
																									102) ||
																							(charCode >=
																								65 &&
																								charCode <=
																									70)
																						)
																					) {
																						// Invalid Unicode escape sequence.
																						abort();
																					}
																				}
																				// Revive the escaped character.
																				value +=
																					fromCharCode(
																						"0x" +
																							source.slice(
																								begin,
																								Index
																							)
																					);
																				break;
																			default:
																				// Invalid escape sequence.
																				abort();
																		}
																	} else {
																		if (charCode == 34) {
																			// An unescaped double-quote character marks the end of the
																			// string.
																			break;
																		}
																		charCode =
																			source.charCodeAt(
																				Index
																			);
																		begin = Index;
																		// Optimize for the common case where a string is valid.
																		while (
																			charCode >= 32 &&
																			charCode != 92 &&
																			charCode != 34
																		) {
																			charCode =
																				source.charCodeAt(
																					++Index
																				);
																		}
																		// Append the string as-is.
																		value += source.slice(
																			begin,
																			Index
																		);
																	}
																}
																if (
																	source.charCodeAt(Index) == 34
																) {
																	// Advance to the next character and return the revived string.
																	Index++;
																	return value;
																}
																// Unterminated string.
																abort();
															default:
																// Parse numbers and literals.
																begin = Index;
																// Advance past the negative sign, if one is specified.
																if (charCode == 45) {
																	isSigned = true;
																	charCode = source.charCodeAt(
																		++Index
																	);
																}
																// Parse an integer or floating-point value.
																if (
																	charCode >= 48 &&
																	charCode <= 57
																) {
																	// Leading zeroes are interpreted as octal literals.
																	if (
																		charCode == 48 &&
																		((charCode =
																			source.charCodeAt(
																				Index + 1
																			)),
																		charCode >= 48 &&
																			charCode <= 57)
																	) {
																		// Illegal octal literal.
																		abort();
																	}
																	isSigned = false;
																	// Parse the integer component.
																	for (
																		;
																		Index < length &&
																		((charCode =
																			source.charCodeAt(
																				Index
																			)),
																		charCode >= 48 &&
																			charCode <= 57);
																		Index++
																	);
																	// Floats cannot contain a leading decimal point; however, this
																	// case is already accounted for by the parser.
																	if (
																		source.charCodeAt(Index) ==
																		46
																	) {
																		position = ++Index;
																		// Parse the decimal component.
																		for (
																			;
																			position < length &&
																			((charCode =
																				source.charCodeAt(
																					position
																				)),
																			charCode >= 48 &&
																				charCode <= 57);
																			position++
																		);
																		if (position == Index) {
																			// Illegal trailing decimal.
																			abort();
																		}
																		Index = position;
																	}
																	// Parse exponents. The `e` denoting the exponent is
																	// case-insensitive.
																	charCode =
																		source.charCodeAt(Index);
																	if (
																		charCode == 101 ||
																		charCode == 69
																	) {
																		charCode =
																			source.charCodeAt(
																				++Index
																			);
																		// Skip past the sign following the exponent, if one is
																		// specified.
																		if (
																			charCode == 43 ||
																			charCode == 45
																		) {
																			Index++;
																		}
																		// Parse the exponential component.
																		for (
																			position = Index;
																			position < length &&
																			((charCode =
																				source.charCodeAt(
																					position
																				)),
																			charCode >= 48 &&
																				charCode <= 57);
																			position++
																		);
																		if (position == Index) {
																			// Illegal empty exponent.
																			abort();
																		}
																		Index = position;
																	}
																	// Coerce the parsed value to a JavaScript number.
																	return +source.slice(
																		begin,
																		Index
																	);
																}
																// A negative sign may only precede numbers.
																if (isSigned) {
																	abort();
																}
																// `true`, `false`, and `null` literals.
																if (
																	source.slice(
																		Index,
																		Index + 4
																	) == "true"
																) {
																	Index += 4;
																	return true;
																} else if (
																	source.slice(
																		Index,
																		Index + 5
																	) == "false"
																) {
																	Index += 5;
																	return false;
																} else if (
																	source.slice(
																		Index,
																		Index + 4
																	) == "null"
																) {
																	Index += 4;
																	return null;
																}
																// Unrecognized token.
																abort();
														}
													}
													// of the source string.
													return "$";
												};

												// Internal: Parses a JSON `value` token.
												var get = function (value) {
													var results, hasMembers;
													if (value == "$") {
														// Unexpected end of input.
														abort();
													}
													if (typeof value == "string") {
														if (
															(charIndexBuggy
																? value.charAt(0)
																: value[0]) == "@"
														) {
															// Remove the sentinel `@` character.
															return value.slice(1);
														}
														// Parse object and array literals.
														if (value == "[") {
															// Parses a JSON array, returning a new JavaScript array.
															results = [];
															for (
																;
																;
																hasMembers || (hasMembers = true)
															) {
																value = lex();
																// A closing square bracket marks the end of the array literal.
																if (value == "]") {
																	break;
																}
																// If the array literal contains elements, the current token
																// should be a comma separating the previous element from the
																// next.
																if (hasMembers) {
																	if (value == ",") {
																		value = lex();
																		if (value == "]") {
																			// Unexpected trailing `,` in array literal.
																			abort();
																		}
																	} else {
																		// A `,` must separate each array element.
																		abort();
																	}
																}
																// Elisions and leading commas are not permitted.
																if (value == ",") {
																	abort();
																}
																results.push(get(value));
															}
															return results;
														} else if (value == "{") {
															// Parses a JSON object, returning a new JavaScript object.
															results = {};
															for (
																;
																;
																hasMembers || (hasMembers = true)
															) {
																value = lex();
																// A closing curly brace marks the end of the object literal.
																if (value == "}") {
																	break;
																}
																// If the object literal contains members, the current token
																// should be a comma separator.
																if (hasMembers) {
																	if (value == ",") {
																		value = lex();
																		if (value == "}") {
																			// Unexpected trailing `,` in object literal.
																			abort();
																		}
																	} else {
																		// A `,` must separate each object member.
																		abort();
																	}
																}
																// Leading commas are not permitted, object property names must be
																// double-quoted strings, and a `:` must separate each property
																// name and value.
																if (
																	value == "," ||
																	typeof value != "string" ||
																	(charIndexBuggy
																		? value.charAt(0)
																		: value[0]) != "@" ||
																	lex() != ":"
																) {
																	abort();
																}
																results[value.slice(1)] =
																	get(lex());
															}
															return results;
														}
														// Unexpected token encountered.
														abort();
													}
													return value;
												};

												// Internal: Updates a traversed object member.
												var update = function (source, property, callback) {
													var element = walk(source, property, callback);
													if (element === undef) {
														delete source[property];
													} else {
														source[property] = element;
													}
												};

												// Internal: Recursively traverses a parsed JSON object, invoking the
												// `callback` function for each value. This is an implementation of the
												// `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.
												var walk = function (source, property, callback) {
													var value = source[property],
														length;
													if (typeof value == "object" && value) {
														// `forEach` can't be used to traverse an array in Opera <= 8.54
														// because its `Object#hasOwnProperty` implementation returns `false`
														// for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`).
														if (getClass.call(value) == arrayClass) {
															for (
																length = value.length;
																length--;

															) {
																update(value, length, callback);
															}
														} else {
															forEach(value, function (property) {
																update(value, property, callback);
															});
														}
													}
													return callback.call(source, property, value);
												};

												// Public: `JSON.parse`. See ES 5.1 section 15.12.2.
												exports.parse = function (source, callback) {
													var result, value;
													Index = 0;
													Source = "" + source;
													result = get(lex());
													// If a JSON string contains multiple tokens, it is invalid.
													if (lex() != "$") {
														abort();
													}
													// Reset the parser state.
													Index = Source = null;
													return callback &&
														getClass.call(callback) == functionClass
														? walk(
																((value = {}),
																(value[""] = result),
																value),
																"",
																callback
															)
														: result;
												};
											}
										}

										exports["runInContext"] = runInContext;
										return exports;
									}

									if (freeExports && !isLoader) {
										// Export for CommonJS environments.
										runInContext(root, freeExports);
									} else {
										// Export for web browsers and JavaScript engines.
										var nativeJSON = root.JSON,
											previousJSON = root["JSON3"],
											isRestored = false;

										var JSON3 = runInContext(
											root,
											(root["JSON3"] = {
												// Public: Restores the original value of the global `JSON` object and
												// returns a reference to the `JSON3` object.
												noConflict: function () {
													if (!isRestored) {
														isRestored = true;
														root.JSON = nativeJSON;
														root["JSON3"] = previousJSON;
														nativeJSON = previousJSON = null;
													}
													return JSON3;
												}
											})
										);

										root.JSON = {
											parse: JSON3.parse,
											stringify: JSON3.stringify
										};
									}

									// Export for asynchronous module loaders.
									if (isLoader) {
										define(function () {
											return JSON3;
										});
									}
								}).call(this);
							}).call(
								this,
								typeof self !== "undefined"
									? self
									: typeof window !== "undefined"
										? window
										: typeof global !== "undefined"
											? global
											: {}
							);
						},
						{}
					],

					51: [
						function (_dereq_, module, exports) {
							module.exports = toArray;

							function toArray(list, index) {
								var array = [];

								index = index || 0;

								for (var i = index || 0; i < list.length; i++) {
									array[i - index] = list[i];
								}

								return array;
							}
						},
						{}
					]
				},
				{},
				[31]
			)(31);
		});
	}

	const { protocol, host } = location;
	const websocketURL = `${host}${namespace}`;
	var ws = window.io(websocketURL);
	ws.on("connection", payload => {
		onConnection({ ...payload, ws });
	});
	ws.on("message", payload => {
		$(window).trigger(TRIGGER_EVENT_NAME, payload);
	});
	ws.on("error", payload => {
		$(window).trigger("error" + TRIGGER_EVENT_NAME, payload);
	});
	ws.on("disconnect" + TRIGGER_EVENT_NAME, payload => {
		$(window).trigger("disconnect" + TRIGGER_EVENT_NAME, payload);
	});
	return ws;
}
</script>
